ブラウザだけでファイルを処理する仕組み
このサイトのツールは、選んだファイルをサーバーに送らない。変換も圧縮も、全部ブラウザの中で終わる。
「サーバーに送りません」と書いてあるサイトは多い。ただ、そう書いてあることと、実際に送っていないことは別だ。仕組みを説明したうえで、読んだ人が自分で確かめる方法まで書いておく。
ファイルは、選んだ時点では読まれていない
<input type="file"> でファイルを選ぶと、JavaScript は File オブジェクトを受け取る。ここで誤解しやすいのだが、この時点ではファイルの中身はまだ読まれていない。
File が持っているのは、名前・サイズ・種類と、ディスク上のファイルへの参照だけだ。中身が必要になったとき、初めてブラウザが読み出す。だから数百MBのファイルを選んでも、選んだ瞬間に固まることはない。
ドラッグ&ドロップも同じで、dataTransfer.files から同じ File が手に入る。入り口が違うだけで、その先の扱いは変わらない。
画像の変換は「一度ピクセルに戻して、書き直す」
このサイトの画像ツールがやっているのは、実質これだけだ。
createImageBitmap(file) ファイルをデコードして、生のピクセルにする
canvas.drawImage(...) その大きさで canvas に描く(ここで縮小もする)
canvas.toBlob(type, q) canvas の中身を、指定した形式で書き出す
JPEGをWebPにする、というのは直接変換しているのではない。一度すべてピクセルに戻して、別の形式で書き直している。だから元がJPEGなら、その時点で失われた情報は戻らないし、縮小してから戻しても細部は復元しない。
toBlob が返すのは Blob で、これはメモリ上のバイト列だ。これを URL.createObjectURL() に渡すと blob: で始まるURLができる。このURLはブラウザの中だけで有効で、外に出ていくものではない。<a download> にそのURLを渡せば、保存できる。
ZIPでまとめる処理も同じ考え方で、Blob をライブラリに渡して別の Blob を作っているだけだ。ここにもサーバーは出てこない。
送っていないことを、どう確かめるか
3通りある。手間が少ない順に書く。
1. 開発者ツールのネットワークタブを見る。ページを開いた後にタブを開き、そこでファイルを選んで変換する。リクエストが1件も増えなければ、送っていない。これが一番早く、このサイトのツールページにも同じ案内を載せている。
2. ネットワークを切る。ページを読み込んだ後にオフラインにして、それでも変換できるか試す。動けば、変換にサーバーは要らないということだ。
3. ソースを読む。このサイトの全ソースを fetch / XMLHttpRequest / sendBeacon /WebSocket で検索すると、0件になる。送る手段そのものが書かれていない。生成されたHTMLに出てくる外部URLも、ライセンス表示のリンク先(GitHub)だけだった。
1と2は誰でもできるが、このサイトを信じる必要がないのが大事なところだと思う。書いてあることを確認する手段が、読む側の手元にある。
サーバーを使わない代償
いいことばかりではない。
端末の性能がそのまま出る。 何十枚もまとめて変換すれば、その処理は全部あなたのCPUがやる。サーバー側で処理するサービスなら、待たされはしても端末は重くならない。
大きなファイルはメモリを食う。 ピクセルに展開する以上、画像の縦横のサイズ分だけメモリが要る。極端に大きい画像は扱えない。
ブラウザが対応していない形式は扱えない。 たとえばHEICは、Chromeが標準ではデコードできない。対応するには変換用のコードを別途読み込むことになり、その分だけ重くなる。このサイトがHEIC変換をまだ用意していないのは、これが理由のひとつだ。
最初にコードを落としてくる必要がある。 ZIP生成に使っているライブラリは116KBある。処理をサーバー側に置けば、この116KBは要らない。
必要なページでだけ読み込む
その116KBを全ページに載せると、記事を読みに来ただけの人にもZIPライブラリが配られることになる。無駄だし、表示も遅くなる。
なのでこのサイトでは、ZIPのコードを使う直前に初めて読み込むようにしている。画像ツールのページを開いても、ファイルを1つだけ変換して単体でダウンロードする限り、ZIPのコードは落ちてこない。複数枚をまとめる段になって、初めて取りに行く。
ビルドの出力を見ると、このライブラリは独立したファイルに分かれていて、トップページや記事ページのコードからは参照されていない。「全部ブラウザでやる」と「全部を最初に配る」は別の話で、後者をやると、ブラウザ内完結の利点が重さで相殺されてしまう。
向き不向き
手元で完結する作りが向いているのは、入力も出力もファイルで、変換の規則が決まっているものだ。画像の形式変換、文字コードの変換、PDFのページ操作。このあたりは全部そうで、サーバーが持つべき情報が何もない。
逆に、大量のデータを突き合わせる処理や、専用のソフトが要る処理、他人と共有する必要があるものは向いていない。そういうものは最初から作らない、という線引きにしている。