1. 導入:なぜStreams APIが重要なのか
Web開発をしていると、サーバーから巨大なデータを受け取ったり、ファイルを読み込んだりする場面に遭遇します。通常、データ全体をメモリに読み込んでから処理を始めると、メモリ不足でブラウザが重くなったり、処理が遅延したりする原因になります。
Streams APIを使うと、データを「小さな塊(チャンク)」として順番に受け取り、処理し始めることができます。これにより、巨大なデータでも少ないメモリで高速に処理できるようになります。
2. 基礎知識:Streams APIの仕組み
Streams APIは、データの流れを「ストリーム」として扱います。イメージとしては「水道の蛇口」です。
・ReadableStream:データを受け取る側(蛇口から出る水を受け止める)
・WritableStream:データを書き込む側(受けた水をバケツに入れる)
・TransformStream:データを加工する側(水を濾過する)
これらを組み合わせることで、データの読み込みと加工をリアルタイムでつなぐことができます。
3. 実装/解決策:データを小分けに処理する
Fetch APIでデータを受け取る際、response.bodyはReadableStreamになっています。これに対してgetReader()を呼び出すことで、データが届くたびに処理を実行するループを構築できます。
4. サンプルプログラム
以下のコードは、サーバーからデータを少しずつ読み込み、コンソールに表示する基本的な例です。
// データを取得する関数
async function fetchAndRead() {
const response = await fetch('https://example.com/large-data.txt');
// ストリームのリーダーを取得
const reader = response.body.getReader();
const decoder = new TextDecoder(); // バイナリをテキストに変換するツール
let result = '';
while (true) {
// データを少しずつ読み込む
const { done, value } = await reader.read();
// データがすべて読み込まれたら終了
if (done) break;
// 読み込んだデータをテキストに変換して表示
const chunk = decoder.decode(value, { stream: true });
console.log('受信したチャンク:', chunk);
}
console.log('読み込み完了!');
}
fetchAndRead();
5. 応用・注意点:現場での活用と回避策
注意点:ストリーム処理では、一度読み込んだデータは「消費」されて消えてしまうため、再度同じデータが必要な場合はコピーを保持する必要があります。また、エラーハンドリングを忘れないようにしましょう。try…catch文で囲むことで、通信が途切れた際にも安全に処理を終了させることができます。
応用:TransformStreamを使えば、受信したデータをその場で圧縮したり、特定のフォーマットに変換しながら表示することも可能です。まずは「データを小分けに読み込んでいる」という感覚を掴むところから始めてみてください。