Streams API 実践:ブラウザでの大容量ファイルストリーム処理

技术架构(更新: 2026年5月31日)

なぜストリーム処理が必要か

従来の大ファイル読み込み:

// ❌ 200MB → 200MB ArrayBuffer → OOM の可能性
const buffer = await file.arrayBuffer();
processEntireBuffer(buffer);

ストリーム処理:

// ✅ 64KB ずつ処理
const stream = file.stream();
for await (const chunk of stream) {
  processChunk(chunk); // 64KB
}
比較 一括読み込み ストリーム
メモリ ファイルサイズ ~64KB(チャンク)
処理開始 読み終わってから 最初のチャンク到着時
200MB 200MB RAM ~64KB RAM
1GB OOM しうる 問題なく動作

3 つのコア Stream

ReadableStream  →  ソース(ファイル、ネットワーク応答)
TransformStream →  中間処理(圧縮、暗号、変換)
WritableStream  →  出力先(ダウンロード、アップロード)

ReadableStream

const response = await fetch('/large-file.pdf');
const reader = response.body!.getReader();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  console.log(`Received ${value.byteLength} bytes`);
}

TransformStream

const compressor = new TransformStream({
  transform(chunk, controller) {
    const compressed = gzipSync(chunk);
    controller.enqueue(compressed);
  }
});

// パイプ
fileStream.pipeThrough(compressor).pipeTo(downloadStream);

バックプレッシャー (Backpressure)

生産が消費より速いとき、Stream は生産側を自動で一時停止します:

FileReader(速い)→ [バッファ満杯] → 読み取り停止
                      ↓
              TransformStream(遅い)→ チャンク消費 → 空き → 再開

手動チャンクループとの差は自動フロー制御で、バッファサイズを手で調整する必要がない点です。


ToolsKu でのストリーム利用

Gzip 圧縮/展開

圧縮・解凍ツール は CompressionStream を使用:

const compressed = file.stream().pipeThrough(new CompressionStream('gzip'));
// 全量読み込みなしのストリーム圧縮

大きな PDF のチャンク読み込み

async function* readPdfChunks(file: File, chunkSize = 4 * 1024 * 1024) {
  let offset = 0;
  while (offset < file.size) {
    const chunk = file.slice(offset, offset + chunkSize);
    yield await chunk.arrayBuffer();
    offset += chunkSize;
  }
}

for await (const chunk of readPdfChunks(largePdf)) {
  await processPdfChunk(chunk);
}

ストリーミングダウンロード

const stream = new ReadableStream({
  async start(controller) {
    for await (const chunk of generateChunks()) {
      controller.enqueue(chunk);
    }
    controller.close();
  }
});

const response = new Response(stream, {
  headers: { 'Content-Disposition': 'attachment; filename="output.zip"' }
});

Stream API の互換性

API Chrome Firefox Safari Edge
ReadableStream 52+ 65+ 10.1+ 79+
TransformStream 80+ 102+ 14.1+ 80+
CompressionStream 80+ 113+ 16.4+ 80+
File.stream() 76+ 69+ 14.1+ 79+

CompressionStream は比較的新しく、非対応ブラウザは pako/fflate で一括処理にフォールバックします。


まとめ

Streams API は大ファイル処理の現代標準です。ReadableStream による分割読み込み、TransformStream による中間処理、バックプレッシャーによる流量制御——これによりブラウザで GB 級ファイルが現実的になり、ToolsKu の大容量ツール(PDF、動画、圧縮)の基盤となっています。

ブラウザローカルツールを無料で試す →

#Streams API#ReadableStream#TransformStream#大文件#流式处理