クライアントサイド PDF 処理:ブラウザローカル PDF ツールの仕組み
クライアントサイド PDF ツールは、サーバーが行うのと同じ処理をユーザーのブラウザ内で行います。本ページはアーキテクチャを理解したい開発者や IT 管理者向けです:どのブラウザ API が関与し、どのライブラリが重処理を担い、ファイルが実際にどこへ行き、正直な限界がどこにあるか。IXPDF を実行例としますが、このモデルは任意のブラウザローカル PDF ツールに適用できます。
パイプライン
ファイル入力からダウンロードまで、サーバーなしで
クライアントサイド PDF 操作のエンドツーエンドの流れは次の通りです:
- ファイル入力。 ユーザーがドロップゾーンにファイルをドロップします。ブラウザはページに
Fileオブジェクト(バイト自体ではなくディスク上のファイルへのポインタ)を渡します。 - メモリへ読み込み。 ページは
file.arrayBuffer()を呼び出し、ページのメモリにArrayBufferとしてバイトを読み込みます。ファイルのバイトがページに存在するのはこの瞬間だけです。まだワーカーにはありません。 - 検証。 ページは処理前にファイル種別(マジックバイト、拡張子)とサイズを検証します。無効なファイルはメインスレッドで即座に失敗し、ワーカーには到達しません。
- Web Worker へ転送。 ページは
ArrayBufferをワーカーへ post します。転送可能転送を使い、バイトをコピーではなく移動します。メインスレッドはバッファへアクセスできなくなります。 - ワーカー内で処理。 ワーカーは PDF ライブラリ(pdf-lib、PDF.js、または WASM コンパイルされた qpdf/mupdf)を呼び出し、PDF を解析・変更します。これが重処理であり、メインスレッドを止めないようバックグラウンドで動きます。
- 結果を返す。 ワーカーは新しい
ArrayBuffer(またはBlob)を生成し、ふたたび転送可能としてメインスレッドへ post します。 - ダウンロードとして提供。 メインスレッドは結果を
Blobで包み、URL.createObjectURL(blob)を呼び出し、<a download>要素でダウンロードとして提供します。メモリリークを避けるため、ダウンロード開始後にオブジェクト URL は revoke されます。
この流れのどこでもファイルはデバイスを離れません。ファイル内容を伴う fetch、XMLHttpRequest、sendBeacon は一切ありません。ページが発するネットワーク要求は、ページ初回ロード時の静的アセット(HTML、JS、CSS、フォント)だけです。
構成要素
関連するブラウザ API とライブラリ
クライアントサイド PDF ツールは小さなブラウザ API のセットと小さな JavaScript ライブラリのセットの上に成り立ちます。それぞれが 1 つの役割を担います。
- File API —
FileとBlobインターフェース。file.arrayBuffer()がバイトをメモリに読み込み、new Blob([bytes], { type: 'application/pdf' })がバイトをダウンロード用にまとめます。 - Web Workers — 独自ヒープを持つバックグラウンドスレッドで、DOM へのアクセスはありません。PDF 解析をここで動かし、メインスレッドを応答性良く保ちます。通信は
postMessage経由。ArrayBufferは第 2 引数を使って転送(コピーではなく移動)できます。 - URL.createObjectURL / URL.revokeObjectURL — メモリ内の結果を指す一時的な
blob:URL を生成し、<a download>要素でダウンロードとして提供できるようにします。URL は revoke しないとリークします。 - pdf-lib — PDF の作成・変更・再保存ができる純 JavaScript PDF ライブラリ。結合・分割・回転・透かし・ページ操作・メタデータ編集に使用。暗号化は未サポート(既知の制限 — 後述)。
- PDF.js — Mozilla の PDF レンダラ。ページをキャンバスへ描画する(PDF から画像への変換)ためと、pdf-lib が読めない PDF を解析するために使用。
- WASM(任意) — ネイティブコードをブラウザでネイティブに近い速度で動かすためのもの。qpdf と mupdf は WASM にコンパイルでき、IXPDF は pdf-lib ではできない操作にこの経路を選択的に使用します。
- CompressionStream — ストリーミング圧縮(gzip、deflate)のためのブラウザネイティブ API。JS 圧縮ライブラリを同梱せずに一部のサイズ削減経路で有用です。
なぜワーカーか
PDF 解析がメインスレッドで動かない理由
PDF 解析は CPU 負荷が高く、同期的な形を持ちます — バイトを読み、オブジェクトを復号し、相互参照をたどり、メモリ内ツリーを構築します。50 MB の PDF は解析に数百ミリ秒、200 MB の PDF は数秒かかることがあります。この処理がメインスレッドで動くと、その間ページは凍結します:アニメーションもスクロールも入力もありません。ブラウザが「ページが応答していません」ダイアログを表示することもあります。
処理を Web Worker へ移すことでこれが解決します。メインスレッドは応答性を保ち、ワーカーがバックグラウンドで PDF を噛み砕き、ページは進捗インジケータを表示し、ワーカーが結果を post した時に UI を更新します。代償は、ワーカーが DOM にアクセスできないため、UI 処理は結果が戻った後にメインスレッドで行う必要があることです。
ワーカーは独自のメモリ予算も持ちます。ワーカーへ転送された大きな PDF はページではなくワーカーのヒープに存在します。これは非常に大きなファイルで重要です:ワーカーが重いバッファを持つ間、ページは軽量に留まられ、バッファはワーカー完了時に解放されます。
転送可能オブジェクト
バイトをコピーではなく移動する
ArrayBuffer が転送なしでワーカーへ post されると、バイトはコピーされます — ワーカーは独自のコピーを得て、メインスレッドはオリジナルを保持します。100 MB の PDF では 200 MB のメモリが使われ、コピー時間も顕著になります。
解決策が転送リストです:postMessage の第 2 引数。バッファを転送リストに載せるとバイトをワーカーへ移動します — メインスレッドの参照はデタッチされ(長さ 0)、ワーカーが所有権を取ります。コピーなし、メモリ倍増なし。結果を戻す際も同じ仕組みを使います。
これは規模が大きくなると大きな差を生む小さな詳細です。転送可能オブジェクトが無ければ、大規模ファイルのクライアントサイド PDF 処理は実用的でありません。
正直な限界
ブラウザがうまくできないこと
クライアントサイド処理は銀の弾丸ではありません。ブラウザでうまくできない、または不可能な操作があり、正直なツールはそれらを偽装せず明示します。
- OCR。 スキャン PDF の光学式文字認識には訓練済みモデルと深刻な CPU が必要です。ブラウザ OCR(Tesseract.js)は存在しますが、品質はデスクトップ Tesseract やクラウド OCR に大きく劣ります。IXPDF は OCR を Research Required と分類しています。
- PDF 暗号化(パスワード保護)。 pdf-lib はまだ暗号化 PDF の書き込みをサポートしません。追加には別のライブラリまたは WASM コンパイルされた qpdf が必要です。IXPDF の PDF 保護ツールは Research Required です。
- PDF から Word/Excel/PowerPoint。 PDF を編集可能な Office ファイルに変換するのはレイアウト再構築問題であり、バックエンドが必要です。試みるブラウザライブラリは低忠実度の出力を生成します。IXPDF はこれらの変換を提供しません。
- AI 要約 / Q&A。 モデルとバックエンドが必要です。2026 年時点で許容品質でクライアントサイドでは不可能です。IXPDF は AI 機能を提供しません。
- 非常に大きなファイル。 ブラウザタブにはメモリ予算(通常数 GB)があります。2 GB の PDF はほとんどのブラウザで OOM します。サーバーサイドツールはストリーミングで扱いますが、ブラウザツールは PDF を同じようにはストリームできません。
正直な対応は、これらを UI で Planned、Research Required、または Future Backend Candidate と分類し、空の出力を返して成功したふりをする偽ツールを出荷しないことです。これがローカルファーストツールとコンテンツファームの「ツール」ページとの境界です。
なぜ重要か
プライバシー特性は構造的であり、約束ではない
クライアントサイド処理が意味のあるプライバシー特性 — 単なるマーケティング主張ではない — である理由は、アップロードなし保証がポリシーではなくコードの構造によって強制されるからです。アップロード先のサーバーが存在しません。ページにはファイル内容を運ぶ fetch 呼び出しがありません。ユーザーは DevTools を開き、Network タブへ行き、操作を実行し、いかなるリクエストもファイルを運ばないことを検証できます。保証は監査可能です。
これは、24 時間後にファイルを削除すると約束するサーバーサイドツールとは異なります。その約束は、あなたが見えないポリシーとインフラによって強制されます。クライアントサイド処理はサーバーの不在によって強制されます。機密ファイルにとって、これが意味のある違いです。
詳しくは IXPDF プライバシーページと IXPDF について を参照してください。
関連記事