ブラウザ内でのローカルなファイル処理の仕組み
何もアップロードしないなら、実際に処理しているのは何で、どこで動いているの?
ここでいう「ローカル」の意味
一般的なオンライン変換サービスは、アップロード用のエンドポイントを持つウェブサイトです。あなたのファイルは自分の管理下にないマシンへ送信され、そこで処理され、一定期間保存され、ダウンロードとして返されます。ローカル処理はこの説明の真ん中を取り除きます。ファイルを読むコードは、すでに開いているブラウザのタブの中で、あなた自身のプロセッサ上で動き、結果はあなた自身のディスクに書き戻されます。
サイト自体は、これまでどおりネットワーク経由で取得されます。HTML、スタイルシート、スクリプト、WebAssemblyモジュールは、他のウェブページと同じようにサーバーから届きます。違いは方向です。プログラムのコードは下りてきますが、あなたのファイルは上がっていきません。
必要な部品はブラウザにすでに揃っている
| 機能 | 提供するもの |
|---|---|
| File APIとBlob API | フォーム送信を経ずに、ユーザーが選択またはドロップしたファイルのバイト列を読み取る |
| Web Workers | 重い処理をバックグラウンドスレッドで実行し、画面の応答性を保つ |
| WebAssembly | C、C++、Rustでコンパイルされたコーデックライブラリをネイティブに近い速度で実行する |
| CanvasとOffscreenCanvas | 画像のデコード、描画、リサイズ、再エンコードを行う |
| WebCodecs | ブラウザ自身のハードウェアアクセラレーション付き動画エンコーダー・デコーダーを利用する |
| WebGPU | モデル推論やピクセルの並列処理をグラフィックスプロセッサ上で実行する |
| File System Access | 対応環境では、ユーザーが指定した場所に結果を直接書き込む |
どれも特殊な技術ではありません。表計算やデザインツール、ゲームをタブの中で動かしているのと同じプラットフォームです。変わっているのは、そこにサーバーを足さないと決めた点だけです。
ファイルがたどる経路
- ファイルを選びます。ブラウザはページにそのハンドルを渡します。コピーではなく参照です。
- ページは先頭の数バイトを読み、拡張子を信用せずにシグネチャから実際のファイル形式を判別します。
- 処理に必要なメモリ量を見積もり、端末が安全に確保できる量を超える場合は処理を断るか、順番待ちに回します。
- バイト列はWeb Workerへ転送されます。ArrayBufferの転送はコピーではなく所有権の移動なので、大きなファイルがメモリ上に二重に存在することはありません。
- ワーカーの内部では、WebAssemblyのコーデックかプラットフォームのAPIが実際のデコードとエンコードを行います。
- 結果はバイト列として返り、Blobに包まれ、ダウンロードとして提示されるか、指定した場所に書き込まれます。
- そのBlobの一時URLは破棄され、バッファは解放されます。
状況を変えたのはWebAssemblyだった
画像や動画のコーデックは、何十年もかけて丹念に最適化されてきたCのコードです。それをJavaScriptで書き直すのは、はじめから現実的ではありませんでした。WebAssemblyは可搬性のあるバイナリ命令形式で、ブラウザはこれをサンドボックス内でネイティブコードに近い速度で実行します。つまり既存のライブラリを、そのままコンパイルしてブラウザへ届けられるということです。
速度と同じくらいサンドボックスも重要です。WebAssemblyモジュールは、ファイルシステムにもネットワークにも他のタブにも、暗黙のうちにアクセスすることはできません。見えるのはページが渡したメモリだけです。悪意のあるコーデックも、単にバグを抱えたコーデックも、渡されていないものを勝手に読みに行くことはできません。
ネットワークを使う部分と、それがあなたのファイルではない理由
ネットワーク経由で届くものは3つです。ページ本体、開いたツールのエンジン、そして背景除去の場合はモデルの重みです。いずれもFileSlimmer自身の静的アセットで、あなたのバイト列が読まれる前にFileSlimmer自身のオリジンから取得されます。どれもダウンロードであり、キャッシュ可能で、一度使ったあとはネットワークをまったく使わずにブラウザ自身のキャッシュから配信できます。
そこから先はすべてローカルです。エンジンがファイルのバイト列を受け取るのは、ページからのpostMessage経由だけです。何かを送信するためのURLが渡されることはありませんし、仮にどこかのコードが試みたとしても、コンテンツセキュリティポリシーがページの接続先を制限します。
トレードオフを率直に整理する
| 観点 | ブラウザ内 | サーバー上 |
|---|---|---|
| ファイルの行き先 | どこにも行かない | 自分の管理下にないマシン |
| 速度 | 端末の性能次第 | 運営者が支払った設備次第 |
| 非常に大きなファイル | ブラウザのメモリが上限 | 運営者が定めた制限が上限 |
| オフラインでの動作 | エンジンがキャッシュされていれば可能 | 不可 |
| 特殊な形式 | WebAssemblyにコンパイルできるものだけ | 運営者が導入したものすべて |
| 1000ファイルの一括処理 | 端末の性能に制約される | たいていこちらが適している |
ローカル処理がいつでも優れているわけではありません。ファイルが人に見せられないものであるとき、端末に十分な性能があるとき、処理がメモリに収まるときに優れています。1台のマシンに収まらない量を処理する必要があるなら、サーバーのほうが優れています。どちらの状況にいるのかをはっきりさせるほうが、片方がすべての場面で勝つと言い張るより役に立ちます。
ここで主張していないこと
これはこのアプリケーションの動作についての説明です。ブラウザ拡張機能についての説明ではありません。拡張機能は、あなたが開いたどのページの内容も読み取れます。OSについての説明でもありません。OSは、あなたが触れるどのファイルも調べられます。ネットワーク事業者についての説明でもありません。事業者には、あなたがそのサイトを訪れたことが分かります。これらはどのウェブサイトの手も届かない範囲であり、そうでないと言うツールは自らの主張を誇張しています。
主張は狭く、検証可能です。選択したファイルはこのブラウザ内でローカルに処理され、FileSlimmerがアップロードすることはありません。次のガイドでは、それを信じるのではなく自分で確かめる方法を説明します。
この作業に使えるツール
出典
- W3C — File API
- W3C — WebAssembly Core Specification
- WHATWG — HTML Standard, Web Workers
- W3C — WebCodecs