ブラウザだけで画像や動画、PDF、データベースまで処理できるようになりました。それでも、大きなファイルになると急に処理が遅くなったり、メモリ不足で失敗したりすることがあります。そこで気になるのが「何GBまでなら大丈夫なのか」という上限ですが、実用上の限界はファイルサイズだけでは決まりません。
10GBのファイルでも一部分ずつ読める処理と、数百MBでも全体を展開して複数の中間データを作る処理では、後者の方が厳しいことがあります。見るべきなのは、ファイルの大きさそのものより「処理中に端末の中で何が起きるか」です。
限界を左右する4つの要素
メモリに何を同時に置くか
元ファイルだけでなく、展開後の画像、デコード済みフレーム、解析用配列、Wasmのメモリ、出力データなどが同時に存在すると使用量が増えます。
どれだけ計算するか
閲覧だけなのか、圧縮・変換・AI解析・再エンコードまで行うのかで処理時間は大きく変わります。
コピーと一時データを何個作るか
同じデータをJavaScript、Worker、Wasm、デコーダー、出力用に複製すると、ファイルサイズ以上のメモリを使うことがあります。
ブラウザと端末の余力
同じWebアプリでも、スマートフォンと高性能PCでは使えるメモリ、CPU性能、対応APIやコーデックが違います。また、大きなファイルではストレージからの読み込みや、処理結果の書き出し速度がボトルネックになることもあります。
ファイルサイズと必要メモリは同じではない
ファイルを選んだ瞬間に、その全バイトが必ずJavaScriptのメモリへコピーされるわけではありません。ブラウザではFile / Blobとしてファイルを参照し、必要に応じて全体をArrayBufferへ読んだり、一部分だけをslice()で取り出したり、stream()で順に読んだりできます。つまり、実装次第では巨大ファイルでも最初から全体をメモリへ載せずに扱えます。
一方、アプリがBlob.arrayBuffer()などでファイル全体を読み込めば、そのバイト列を保持するメモリが必要になります。さらに、その後の処理で別の形式へ展開したり、中間結果を作ったりすれば、必要量はファイルサイズを超えます。『500MBのファイルだから500MBあれば足りる』とは考えない方が安全です。
圧縮されたファイルは、処理中に大きく展開されることがある
JPEGやZIP、一般的な動画ファイル、圧縮されたParquetなどでは、保存時のデータ量が処理時のデータ量より小さいことがあります。処理内容によっては、その圧縮されたデータを一度「計算しやすい形」へ展開する必要があり、展開後サイズが元ファイルの容量よりずっと大きくなることがあります。
画像は分かりやすい例です。CanvasのImageDataを一般的な8bit RGBAで扱う場合、1画素につき4つの値を持ちます。8000×6000ピクセルなら、画素データだけで約1億9200万バイトです。圧縮後のJPEGが数十MBでも、編集や解析の途中では約192MB相当の画素データを扱うことがあります。さらに元画像、加工前、加工後のCanvasを同時に持てば、その分だけ増えます。
コピーと一時バッファが、見えないメモリ使用量を増やす
処理中は、同じ内容が複数の場所に存在することがあります。たとえば、元のファイルをArrayBufferへ読み、Workerへ渡し、Wasmエンジンのメモリへコピーし、処理結果を別の配列へ出し、最後にBlobとして保存用データを作る、という流れです。すべての実装がこの通りにコピーするわけではありませんが、設計によっては一時的に複数世代のデータが重なります。
Web WorkerへArrayBufferを渡すときは、Transferableとして所有権を移すことで、同じバッファを複製せずに渡せる仕組みがあります。大きなデータでは、こうした『コピーを減らす設計』が実用上の上限にかなり効きます。
Workerに移せば『軽くなる』わけではない
Web Workerは、時間のかかるJavaScript処理を画面描画などを担当するメインスレッドとは別のスレッドで実行できます。そのため、重い解析中でもボタンや進捗表示が固まりにくくなります。これは大容量ファイルのUXではとても重要です。
ただし、Workerへ移しただけで計算量が減るわけではありません。動画のエンコードに10秒分の計算が必要なら、その計算自体はどこかのCPUコアで行う必要があります。並列化された処理なら複数コアを使って速くなる場合もありますが、Worker化と『処理が軽いこと』は別です。
WebAssemblyを使う処理には、Wasm側のメモリもある
FFmpegやDuckDBのような既存エンジンをWebAssemblyで動かす場合、エンジンはWebAssembly.Memoryという線形メモリを使います。実装によっては、必要に応じてこのメモリを拡張しながら、入力、作業領域、結果などを保持します。
ページ全体で見ると、Wasmのメモリだけが存在するわけではありません。JavaScript側のArrayBuffer、Canvas、ブラウザのデコーダーが使うバッファ、DOM、出力用Blobなども同じ端末上のメモリを使います。そのため『Wasmのメモリ上限だけ見れば分かる』わけではなく、処理全体のピーク使用量を見る必要があります。
大容量ファイルに強いツールは『全部読む』とは限らない
ファイル形式や処理内容が許せば、全体を一度にメモリへ載せずに済みます。File / Blobは一部分だけをslice()で取り出したり、ReadableStreamとして順に読んだりできます。データファイルならページ表示に必要な範囲だけ読む、ログなら行単位で走査する、列指向ファイルなら必要な列やブロックだけ読む、といった設計ができます。
この差は大きく、1GBのファイルでも必要な数MB〜数十MBだけを順番に処理できれば、メモリ面では扱いやすくなる場合があります。逆に数百MBでも、全体を展開し、元データ・中間データ・出力を同時に持つ処理は厳しくなります。ただし、すべての形式・操作がストリーム処理できるわけではなく、ランダムアクセスや全体情報が必要な処理もあります。
同じ『大容量』でも、重くなる場所は違う
大容量ファイルという言葉だけでは、どこが限界になるかは分かりません。画像、動画、PDF、データベースでは、負荷のかかる場所が違います。
特に、「開ける」と「変換できる」は別です。メタデータや一部のレコードだけを読む処理は軽くても、画像全体の展開や動画の全フレーム再エンコード、データ全体のソートのような処理では、同じファイルでもCPUとメモリの負荷が大きく変わります。
| 対象 | 重くなりやすい処理 | 実用上のポイント |
|---|---|---|
| 画像 | 高解像度画像の展開、複数Canvas、ぼかし・変換、再圧縮 | 圧縮後のファイル容量より縦×横の画素数が効くことがある |
| 動画・音声 | デコード、エンコード、フレーム処理、音声処理、コンテナ再構成 | 容量だけでなく解像度、長さ、コーデック、変換内容が効く |
| PDF・アーカイブ | ページ画像化、埋め込み画像、展開、複数ファイルの保持 | ページ数だけでなく高解像度画像や展開後サイズも見る |
| データ・DB | 解析、解凍、SQL、ソート・集計、中間テーブル | 必要範囲だけ読める形式・クエリなら全体サイズより軽くできる |
では、何GBまでなら大丈夫なのか
残念ながら、すべてのブラウザ・端末・ファイル形式に共通する『○GBまで』という数字はありません。実用上の上限は、端末の物理メモリ、他のタブやアプリが使っているメモリ、OSやブラウザのメモリ管理、Wasmやデコーダーの使い方、処理アルゴリズムなどの組み合わせで変わります。
そのため、ツール側が『最大2GB』のような上限を案内する場合、それはブラウザ一般の仕様ではなく、そのツールの実装・テスト範囲として示していることがあります。大容量対応を判断するときは、ファイルサイズの数字だけでなく、処理が全読み込み型か、分割処理できるか、キャンセルできるか、進捗が見えるか、スマートフォンでも想定されているかを見る方が実用的です。
Browser Kittyでも『ローカルだから無制限』とは考えない
Browser Kittyでは、ユーザーファイルを外部へ送らずに済む処理はできるだけ端末内で完結させています。ただし、ローカル処理はサーバーの代わりに利用者のCPUとメモリを使う方式でもあります。完全ローカルであることと、大容量ファイルを無制限に扱えることは別です。
そのため、データViewerのように現在ページや必要なブロックだけ読む設計が有効な場面もあれば、動画圧縮のようにデコードと再エンコードが必要で端末性能の影響を大きく受ける場面もあります。ブラウザ内処理の良さを活かすには、ファイルを外へ送らないことだけでなく、メモリ使用量、キャンセル、進捗、エラー状態まで含めて設計する必要があります。
大容量ファイルを扱う前に見る4つのポイント
『何MB / 何GBあるか』だけを見るより、次の4点を見る方が、そのツールで現実的に扱えそうか判断しやすくなります。
- ファイルの中身を見る画像なら縦×横の解像度、動画なら解像度・長さ・コーデック、PDFならページ数と埋め込み画像、データなら行数・列数・圧縮方式なども確認します。ファイル容量だけでは処理量を判断できません。
- 処理の種類を見る閲覧・メタデータ確認だけなのか、再圧縮・エンコード・AI解析・全体ソートまで行うのかを見ます。同じファイルでも処理内容でCPUとメモリの負荷は大きく変わります。
- 全読み込みか分割処理かを見る必要な範囲だけ読むViewerやストリーム処理なら大容量でも扱いやすくなることがあります。反対に、最初に全体をArrayBufferへ読み込み、複数の中間データを作る処理ではピークメモリが大きくなります。
- 端末と失敗時の挙動を見るスマートフォンではPCより余裕が少ない場合があります。長時間処理では進捗表示、キャンセル、失敗後の再試行、入力を失わない設計があるかも確認すると安心です。
動画圧縮
動画の解像度・ビットレートなどを調整してブラウザ内で圧縮します。
注意点
- 『開ける』と『変換できる』は別です。メタデータだけ読む処理は軽くても、全フレームの再エンコードは重いことがあります。
- 高解像度画像では、圧縮後のJPEG / WebP容量より、展開後の画素数がメモリ使用量に強く効くことがあります。
- WorkerはUIの固まりを減らす仕組みです。処理時間やメモリ使用量が必ず減るわけではありません。
- 分割読み込みやストリーム処理は有効ですが、形式や操作によっては全体情報やランダムアクセスが必要で、完全な逐次処理にできない場合があります。
- 別タブや他のアプリも同じ端末メモリを使います。同じファイルでも、その時の端末状態によって成功・失敗や速度が変わることがあります。
よくある質問
1GBのファイルはブラウザで扱えますか?
扱える場合もありますが、1GBという数字だけでは判断できません。必要な部分だけ順に読むViewerと、全体をメモリへ読み込んで展開・変換するツールでは負荷が大きく違います。端末、ブラウザ、形式、処理内容、実装方式を合わせて見る必要があります。
ファイルを選んだだけで、同じ容量のメモリを使いますか?
必ずしもそうではありません。File / Blobはファイルを表すオブジェクトで、アプリは必要な範囲を後から読めます。ただし、arrayBuffer()などで全体を読み込んだり、デコード後のデータや中間結果を作ったりすると、その分のメモリが必要になります。
Web Workerを使えば大容量ファイルでも安全ですか?
Workerは重い処理をメインスレッドから分離し、画面を固まりにくくするのに有効です。ただしメモリ不足やCPU負荷そのものを解決する仕組みではありません。ArrayBufferをTransferableとして渡してコピーを減らすなど、別の設計も重要です。
WebAssemblyならデスクトップアプリと同じように大容量を扱えますか?
同じとは限りません。WebAssemblyは高速な処理エンジンをブラウザ内で動かしやすくしますが、ブラウザのサンドボックス、メモリ管理、利用できるAPI、端末性能の影響は残ります。Wasmを使っていることだけでは大容量対応を保証できません。
大きな動画が重いのは、ファイル容量が大きいからですか?
容量だけではありません。解像度、再生時間、フレームレート、コーデック、音声、変換内容が影響します。特に再エンコードでは、動画をデコードして各フレームを処理し、再びエンコードする計算が必要です。
参考資料
ブラウザがファイルを部分的・逐次的に読む仕組み、Canvasの画素データ、Web Workerとデータ移譲、WebAssemblyの線形メモリについて、以下の公式仕様・公式資料を参照しています。実際のメモリ上限や処理可能サイズはブラウザ、OS、端末、Webアプリの実装によって異なります。
- W3C File API
- MDN Web Docs ImageData: data プロパティ
- MDN Web Docs Blob: stream() メソッド
- MDN Web Docs ウェブワーカー API
- MDN Web Docs 移譲可能オブジェクト
- MDN Web Docs WebAssembly.Memory