コンテンツにスキップ
getnextpdf.com

Fast Web View — PDF がダウンロードを終える前に開く仕組み

Spec: ISO 32000-2, Annex F

リニアライズされた PDF は、最初のページと小さなナビゲーションインデックスがファイルの一番先頭に位置するよう、再編成されています。そのためビューアは、文書の残りがまだ届いている最中でも 1 ページ目を描画でき、2 ページから 146 ページまでを先に読むことなく 147 ページへ直接ジャンプできます。

これは、多くの読者がその親しみやすい名前で知っている機能です。Fast Web View です。

電波が 1 本しか立っていない電話で 200 ページのレポートを開くところを想像してください。リニアライゼーションがなければ、ビューアは何かを描画する前にファイルの一番最後を必要とすることがしばしばです。なぜなら、すべてのオブジェクトがどこに存在するかを告げるマスターインデックスが、伝統的には後ろに位置するからです。だからあなたは、最初の 1 ページを読むためだけに、200 ページがダウンロードされるあいだスピナーを眺めることになります。

リニアライゼーションがあれば、ファイルは「1 ページ目に何があるか」への答えが回線から最初に届くように配置されます。リーダーは 1 ページ目を 1 秒で描き、残りはスクロールやジャンプに応じてのみ取得します。高速な接続では、まったく気づかないかもしれません。低速な、あるいは従量制の接続では、それは使える文書と放棄されたタブとの差です。

  • リニアライズされたファイルは 先頭に集約 されています。1 ページ目と ヒントテーブル が、ボディの残りより前に置かれます。
  • ヒントテーブルは レンジ の地図です。どのバイトレンジが各ページと共有オブジェクトに属するかをビューアに告げ、ビューアがサーバーに まさにそれらのスライス だけを求められるようにします。そのうえでクロスリファレンステーブルが、各オブジェクト番号をその正確なオフセットへ解決します。
  • これは バイトレンジリクエスト に依存します。ビューアが、ファイル全体ではなく、必要に応じてスライスを取得することです。
  • バイトは通常の PDF と内容的に同一です。リニアライゼーションが変えるのは 順序とインデックス であって、ページそのものではありません。
  • それは NextPDF における 1 つの明示的で切り替え可能なステップです。最善を期待するフラグではなく、本物の 3 パス再構築によって生成されます。

すべてがどれだけ大きいかを正確に知るまでは、ページを先頭に集約することはできません。なぜならヒントテーブルはバイトオフセットを記録し、オフセットはすべてのオブジェクトの長さが確定して初めて正しくなるからです。この循環性 — オフセットはサイズに依存し、サイズはレイアウトに依存する — こそが、リニアライザが 1 回の走査ではなく複数のパスで動く理由です。

NextPDF はこれを、決定論的な 3 パス再構築で解決します。第 1 パスは測定し、第 2 パスは配置を決め、第 3 パスは、いまや判明したオフセットを焼き込んだ実バイトを書きます。

  1. MEASURESerialise every object once to learn its exact byte length. Offsets are circular — they depend on sizes — so sizes are pinned first.
  2. PLACEDecide the order: first page and its dependencies up front, then the rest. Reserve space for the linearization parameter dictionary and the hint table.
  3. FILLWrite the final bytes. Each reserved field is filled with values computed after MEASURE and PLACE — the first-page length, the hint-table location, the main cross-reference offset — derived from the measured sizes and the chosen placement.
The three-pass linearization rebuild. MEASURE sizes every object so lengths are final; PLACE decides the front-loaded order and reserves the hint-table region; FILL writes the real bytes with the now-known offsets, so the first page and the hint table land at the front and the cross-reference data resolves on first fetch.

出力は、最初のオブジェクトとして リニアライゼーションパラメータディクショナリ を携え、標準が規定するとおりに、ページをインデックス化する 1 つ以上の ヒントテーブル を携えます(Spec: ISO 32000-2, Annex F)。それらのヒントテーブルは、伝統的な クロスリファレンステーブル並んで 働きます。ヒントテーブルがビューアの取得すべきバイトレンジと位置を記録する一方、クロスリファレンステーブルは各オブジェクト番号をその正確なバイトオフセットへ対応づけるインデックスです。NextPDF のリニアライザは古典的なテーブル形式を送出し、その過程でクロスリファレンスストリームがあれば追い出します。そのため、いったんスライスが届けば、リーダーはそのテーブルから直接オフセットによってオブジェクトを解決します(Spec: ISO 32000-2, §7.5.4)。

役に立つメンタルモデルがあります。通常の PDF は、目次が 表紙に糊付けされた本です。リニアライズされた PDF は、その目次ページを先頭に移し、ページごとのページ番号インデックスを加えます。だから任意のページへ直接開けます。章は変わりません。動いたのはナビゲーションだけです。

リニアライゼーションは明示的で切り替え可能なステップです。あなたが求め、エンジンが再構築を行い、Fast-Web-View ファイルを送出します。

<?php
declare(strict_types=1);
use NextPDF\Core\Document;
use NextPDF\Contracts\OutputDestination;
$document = Document::createStandalone();
$document->setTitle('Annual Report');
for ($page = 1; $page <= 200; $page++) {
$document->addPage();
$document->setFont('helvetica', '', 12);
$document->cell(0, 12, "Page {$page}", newLine: true);
}
// Linearization is requested explicitly — an operability choice, not a default.
// enableLinearization() takes no arguments; it is the on-switch. The engine
// runs the MEASURE -> PLACE -> FILL rebuild and emits a Fast-Web-View file
// with the first page and hint table at the front.
$document->enableLinearization();
$bytes = $document->output(dest: OutputDestination::String);

ページコンテンツは、あなたが作成したものそのままです。違いは、受け取るバイトの ファイル順序 にあり、そしていまや上部近くに位置するヒントテーブルにあります。

結果は、見知らぬ第三者がするのと同じ流儀で検証します。外部のチェッカーで、です。

$ qpdf --check-linearization report.pdf
report.pdf: no linearization errors

qpdf --check-linearization は、単にフラグを探すだけではありません。ファイルが 主張する オフセットを再導出し、それらが真であることを確認します。1 ページ目のオブジェクトが本当にリニアライゼーションディクショナリの言う場所にあること、ヒントテーブルが正しいバイトを指していること、そして構造が Annex F に準拠していること、です。自分自身のレイアウトについて嘘をつくファイルは、一見リニアライズされているように見えても、このチェックに失敗します。

よくある思い込みは、リニアライゼーションがファイルを圧縮する、あるいはダウンロードを全体として速くするというものです。それはどちらもしません。リニアライズされたファイルは、しばしば数バイト 大きく なります。追加のヒントテーブルを携えるからです。文書全体の総転送時間は、本質的に変わりません。

変わるのは、最初の有用なピクセルがいつ現れるか です。リニアライゼーションが最適化するのは 最初のページまでの時間 であって、総バイト数ではありません。それはレイテンシ機能であって、圧縮機能ではありません。1 ページ目を早くストリーミングすることと、ファイルを速くダウンロードすることは別の目標であり、リニアライゼーションは前者に資します。

第 2 の誤解は、どんな Web サーバーでもリニアライズされたファイルをストリーミングする、というものです。ビューアはバイトレンジを取得する必要があり、それはサーバーが HTTP のレンジリクエストに応じなければならないことを意味します。ほとんどは応じますが、常にファイル全体を返すサーバーは、Fast Web View を再び遅いファイル全体の待ち時間へと戻してしまいます。ファイルはストリーミングの用意ができていても、トランスポートが用意できていないのです。

NextPDF は、リニアライズされたファイルの生成について完全なコアサポートを備えています。パラメータディクショナリとヒントテーブルを送出し、外部の Annex F チェックに合格する、本番品質の 3 パスリニアライザです。

Fast Web View (linearization) output — edition availability
EditionAvailability
Core

Full support. NextPDF produces linearized (Fast Web View) output through a production three-pass MEASURE → PLACE → FILL rebuild, conforming to ISO 32000-2 Annex F.

ProNot in this edition
EnterpriseNot in this edition

名前を挙げるに値する 2 つの境界があります。第 1 に、リニアライゼーションは 1 つのリビジョン の性質です。インクリメンタル更新 — 署名、フォーム入力、編集 — を追記した瞬間に、追記されたバイトは末尾に行き、ファイルは再構築されるまで厳密にはもはやリニアライズされていません。それは欠陥ではなく通常のトレードオフです。追記が署名済み文書にとって正しい振る舞いである理由については、インクリメンタル更新を参照してください。

第 2 に、エンジンはファイルを制御しますが、ネットワークは制御しません。Fast Web View がその約束を果たすのは、配信する接続がバイトレンジリクエストに応じるときだけです。バイトが完璧にリニアライズされていても、サーバーがファイル全体を送ると言い張れば、1 つの遅い塊として届くことになります。

  • The anatomy of a PDF file — リニアライゼーションが 並べ替える ヘッダー、ボディ、クロスリファレンステーブル、そしてトレーラー。何が並べ替えられるのかを見るために、まずこれを読んでください。
  • Memory and streaming — 書き込み側のストリーミングという別の軸。NextPDF がバイトを 生成 しながらメモリをどう平らに保つか、対して リーダー がそれらをどうストリーミングするか。
  • Incremental updates and why they matter — なぜ後の編集が末尾に追記されるのか、そしてそれがリニアライズされたファイルの先頭集約レイアウトにとって何を意味するか。
  • Streams and filters — ヒントテーブルが指すボディオブジェクトの内側に何があり、それらがどう圧縮されるか。
  • リニアライゼーション(Linearization) — ビューアがファイル全体の到着前に描画・ナビゲーションできるよう、最初のページとナビゲーションインデックスを先頭に集約する再構築。その結果に対する標準の名称。
  • Fast Web View — リニアライズされた PDF の、消費者向けの名称。2 つの用語は同じファイルを指す。
  • ヒントテーブル(Hint table) — リニアライズされたファイルの内側にある構造で、各ページと共有オブジェクトのバイト レンジと位置 を記録し、ビューアがどのスライスを要求すべきかを知らせる。そのうえでクロスリファレンステーブルが、オブジェクト番号をその正確なバイトオフセットへ対応づける。
  • リニアライゼーションパラメータディクショナリ(Linearization parameter dictionary) — リニアライズされたファイルの最初のオブジェクト。オンデマンドの取得を可能にする鍵となるオフセット(1 ページ目の長さ、ヒントテーブルの位置、メインのクロスリファレンス位置)を宣言する。
  • バイトレンジリクエスト(Byte-range request) — ファイル全体ではなくそのスライスを求める HTTP リクエスト。Fast Web View が依存するトランスポート機構。
  • 最初のページまでの時間(Time-to-first-page) — 読者が 1 ページ目を目にするまでの時間。リニアライゼーションが最適化するレイテンシで、総ダウンロード時間とは別物。