はじめに
Web開発をしていると、画像のアップロード、動画の生成、ファイルのダウンロードなど、ファイルを扱う機会が多くあります。そんなとき、ブラウザの内部では「Blob」という仕組みが活躍しています。
この記事では、Blobとは何か、どのように使われるのかを、図解と実例を交えて解説します。
Blobの基本概念
Blobの定義
Blob = Binary Large Object(バイナリ・ラージ・オブジェクト)
簡単に言うと、ブラウザのメモリ上に保存された「ファイルのようなもの」です。実際のファイルシステムには保存されず、ブラウザのメモリ内に一時的に存在するデータの塊を指します。
ファイルシステムとの違い
通常のファイルは、ハードディスクやSSDなどのストレージに保存されます。一方、Blobはブラウザのメモリ上にのみ存在し、ページを閉じると消えてしまいます。
この特性により、以下のようなメリットがあります。
- サーバーとのやり取りなしに、ブラウザ内でデータを一時的に保持できる
- ユーザーのストレージを消費しない
- 動的に生成されたデータを即座に扱える
Blobの仕組みを図解で理解する
パソコンのファイルとBlobの比較
Blobの構造
Blobは以下の3つの要素で構成されています。
- バイナリデータ: 画像、動画、テキストなどの実際のデータ
- サイズ: データのバイト数
- MIMEタイプ: データの種類を表す文字列(image/png、video/mp4など)
Blobが使われる実践的な場面
画像をアップロードして動画を生成するアプリケーションを例に、Blobの使われ方を見ていきましょう。
データの流れ全体像
FileオブジェクトとBlobの関係
実は、FileオブジェクトはBlobを継承しています。つまり、ユーザーが選択したファイルは既にBlobの一種なのです。
// ユーザーが画像を選択
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', (e) => {
const file = e.target.files[0]; // File オブジェクト
console.log(file instanceof Blob); // true
console.log(file.name); // "画像1.jpg"
console.log(file.size); // 1048576 (バイト)
console.log(file.type); // "image/jpeg"
});
サーバーとのデータのやり取り
// 画像を送信
const formData = new FormData();
formData.append('image1', file1);
formData.append('image2', file2);
const response = await axios.post('/api/generate', formData);
// サーバーから動画データ(Blob)を受け取る
const videoBlob = new Blob([response.data], { type: 'video/mp4' });
Blobの実装例
Blobの作成方法
Blobは様々な方法で作成できます。
// 1. テキストからBlobを作成
const textBlob = new Blob(['Hello, World!'], { type: 'text/plain' });
// 2. JSON データからBlobを作成
const jsonData = { name: 'John', age: 30 };
const jsonBlob = new Blob([JSON.stringify(jsonData)], { type: 'application/json' });
// 3. バイナリデータからBlobを作成
const arrayBuffer = new ArrayBuffer(8);
const binaryBlob = new Blob([arrayBuffer], { type: 'application/octet-stream' });
Blob URLの生成と使用
Blobをブラウザで表示するには、Blob URLを生成します。
// Blob URLを生成
const blobURL = URL.createObjectURL(videoBlob);
// 結果: "blob:http://localhost:3000/550e8400-e29b-41d4-a716-446655440000"
// 動画要素で使用
const videoElement = document.querySelector('video');
videoElement.src = blobURL;
// 画像要素で使用
const imgElement = document.querySelector('img');
imgElement.src = blobURL;
// ダウンロードリンクとして使用
const downloadLink = document.querySelector('a');
downloadLink.href = blobURL;
downloadLink.download = 'video.mp4';
メモリ解放の重要性
Blob URLは手動で解放する必要があります。解放しないとメモリリークの原因になります。
// Blob URLを生成
const blobURL = URL.createObjectURL(videoBlob);
// 使用後は必ず解放
URL.revokeObjectURL(blobURL);
Reactでの実装例を見てみましょう。
import { useEffect, useState } from 'react';
function VideoPlayer({ videoBlob }) {
const [blobURL, setBlobURL] = useState('');
useEffect(() => {
// Blob URLを生成
const url = URL.createObjectURL(videoBlob);
setBlobURL(url);
// クリーンアップ関数でメモリ解放
return () => {
URL.revokeObjectURL(url);
};
}, [videoBlob]);
return <video src={blobURL} controls />;
}
Blobのダウンロード実装
生成したBlobをファイルとしてダウンロードする実装例です。
function downloadBlob(blob: Blob, filename: string) {
// Blob URLを生成
const blobURL = URL.createObjectURL(blob);
// ダウンロード用のリンクを作成
const link = document.createElement('a');
link.href = blobURL;
link.download = filename;
// クリックイベントを発火
document.body.appendChild(link);
link.click();
// 後片付け
document.body.removeChild(link);
URL.revokeObjectURL(blobURL);
}
// 使用例
const videoBlob = new Blob([videoData], { type: 'video/mp4' });
downloadBlob(videoBlob, 'generated-video.mp4');
まとめ
Blobを使うメリット
- 柔軟なデータ操作: ブラウザ内でファイルのようなデータを自由に扱える
- 一時的な保存: ストレージを消費せずにデータを保持できる
- 動的な生成: プログラムで生成したデータを即座にファイルとして扱える
- サーバーレス処理: 一部の処理をブラウザ内で完結できる
実装時の注意点
-
メモリ管理: 使い終わったBlob URLは必ず
URL.revokeObjectURL()で解放しましょう - サイズ制限: ブラウザのメモリには限りがあるため、巨大なファイルには注意が必要です
- 永続化の必要性: Blobはページを閉じると消えるため、保存が必要なデータは別途サーバーに送信しましょう
Blobを理解することで、ファイルアップロード、動画生成、画像編集など、より高度なWeb アプリケーションの開発が可能になります。ぜひ実際のプロジェクトで活用してみてください。