Fast Web View: как PDF открывается ещё до завершения загрузки
Spec: ISO 32000-2, Annex FISO 32000-2 Annex F
Линеаризованный PDF переупорядочен так, что первая страница и небольшой навигационный индекс находятся в самом начале файла. Поэтому программа просмотра может отрисовать первую страницу, пока остальная часть документа ещё приходит, и перейти сразу к странице 147, не читая сначала страницы со 2-й по 146-ю.
Это та возможность, которую большинство читателей знает под дружелюбным именем: Fast Web View.
Почему это важно
Заголовок раздела «Почему это важно»Представьте отчёт на 200 страниц на телефоне с одной палочкой сигнала. Без линеаризации программе просмотра часто нужен самый конец файла, прежде чем она сможет хоть что-то отрисовать, потому что главный индекс, в котором сказано, где находится каждый объект, традиционно лежит в конце. Поэтому вы смотрите на крутящийся индикатор, пока загружаются двести страниц, лишь бы прочитать первую.
С линеаризацией файл устроен так, что ответ на вопрос «что на первой странице» приходит из канала первым. Программа отрисовывает первую страницу за секунду, а остальное забирает только по мере прокрутки или перехода. На быстром соединении вы можете этого вовсе не заметить. На медленном или тарифицируемом — это разница между пригодным документом и закрытой вкладкой.
Если коротко
Заголовок раздела «Если коротко»- Линеаризованный файл вынесен вперёд: первая страница и таблица подсказок размещены первыми, перед остальным телом.
- Таблица подсказок — это карта диапазонов. Она сообщает программе просмотра, какие диапазоны байтов относятся к каждой странице и к общим объектам, чтобы программа могла запросить у сервера именно эти срезы, — а затем таблица перекрёстных ссылок разрешает каждый номер объекта в его точное смещение.
- Это опирается на запросы диапазонов байтов — программа просмотра забирает срезы файла по запросу, а не файл целиком.
- Содержимое байтов идентично обычному PDF. Линеаризация меняет порядок и индекс, а не сами страницы.
- В NextPDF это один явный, включаемый шаг — он выполняется настоящей трёхпроходной пересборкой, а не флагом, который надеется на лучшее.
Как NextPDF подходит к этому
Заголовок раздела «Как NextPDF подходит к этому»Нельзя вынести страницу вперёд, пока вы точно не знаете, насколько велико всё остальное, потому что таблица подсказок записывает смещения в байтах, а смещение становится верным только тогда, когда длина каждого объекта окончательна. Эта цикличность — смещения зависят от размеров, размеры зависят от компоновки — и есть причина, по которой линеаризатор работает проходами, а не одним прогоном.
NextPDF решает это детерминированной трёхпроходной пересборкой. Первый проход измеряет, второй принимает решение о размещении, третий записывает реальные байты с уже известными вшитыми смещениями.
- MEASURESerialise every object once to learn its exact byte length. Offsets are circular — they depend on sizes — so sizes are pinned first.
- PLACEDecide the order: first page and its dependencies up front, then the rest. Reserve space for the linearization parameter dictionary and the hint table.
- 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.
В выводе первым объектом идёт словарь параметров линеаризации, а также одна или несколько таблиц подсказок, индексирующих страницы, — ровно так, как предписывает стандарт (Spec: ISO 32000-2, Annex FISO 32000-2 Annex F). Эти таблицы подсказок работают вместе с традиционной таблицей перекрёстных ссылок — они записывают диапазоны и расположения байтов, которые программе просмотра нужно запросить, тогда как таблица перекрёстных ссылок — это индекс, сопоставляющий каждому номеру объекта его точное смещение в байтах. Линеаризатор NextPDF выдаёт классическую табличную форму и попутно вытесняет любой поток перекрёстных ссылок, так что, как только срез приходит, программа чтения разрешает объект по его смещению прямо из этой таблицы (Spec: ISO 32000-2, §7.5.4ISO 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.pdfreport.pdf: no linearization errorsqpdf --check-linearization не просто ищет флаг. Он заново выводит смещения,
которые файл заявляет, и подтверждает, что они истинны: что объекты первой
страницы действительно находятся там, где сказано в словаре линеаризации, что
таблица подсказок указывает на нужные байты и что структура соответствует
Annex F. Файл, который лжёт о собственной компоновке, не проходит эту проверку,
даже если на первый взгляд выглядит линеаризованным.
Распространённое заблуждение
Заголовок раздела «Распространённое заблуждение»Частое предположение в том, что линеаризация сжимает файл или ускоряет загрузку в целом. Она не делает ни того, ни другого. Линеаризованный файл нередко на несколько байтов больше, потому что несёт дополнительные таблицы подсказок. Полное время передачи всего документа практически не меняется.
Что меняется — это когда появляется первый полезный пиксель. Линеаризация оптимизирует время до первой страницы, а не общий объём байтов. Это функция задержки, а не сжатия. Раннее потоковое отображение первой страницы и быстрая загрузка файла — разные цели, и линеаризация служит первой.
Второе заблуждение — что любой веб-сервер будет отдавать линеаризованный файл потоком. Программе просмотра нужно забирать диапазоны байтов, а значит, сервер должен поддерживать HTTP-запросы диапазонов. Большинство поддерживает, но сервер, который всегда возвращает файл целиком, превращает Fast Web View обратно в медленное ожидание всего файла — файл готов к потоковой передаче, а транспорт нет.
Пределы и границы
Заголовок раздела «Пределы и границы»NextPDF имеет полную поддержку производства линеаризованных файлов в ядре: промышленный трёхпроходной линеаризатор, который выдаёт словарь параметров и таблицы подсказок и проходит внешнюю проверку Annex F.
| Edition | Availability |
|---|---|
| Core | Полная поддержка. NextPDF производит линеаризованный вывод (Fast Web View) через промышленную трёхпроходную пересборку MEASURE → PLACE → FILL, соответствующую ISO 32000-2 Annex F. |
| Pro | Not in this edition |
| Enterprise | Not in this edition |
Стоит назвать две границы. Первая: линеаризация — это свойство одной редакции. В тот момент, когда вы добавляете инкрементное обновление — подпись, заполнение формы, правку, — добавленные байты идут в конец, и файл больше не является строго линеаризованным, пока его не пересоберут. Это нормальный компромисс, а не дефект; см. инкрементные обновления о том, почему добавление — правильное поведение для подписанных документов.
Вторая: движок управляет файлом. Он не управляет сетью. Fast Web View выполняет своё обещание только тогда, когда обслуживающее соединение поддерживает запросы диапазонов байтов; байты могут быть идеально линеаризованы и всё равно прийти одним медленным куском, если сервер настаивает на отправке всего файла.
Связанная документация
Заголовок раздела «Связанная документация»- Анатомия файла PDF — заголовок, тело, таблица перекрёстных ссылок и трейлер, которые линеаризация переупорядочивает. Прочтите это сначала, чтобы увидеть, что именно переупорядочивается.
- Память и потоковая обработка — потоковая обработка на стороне записи, другая ось: как NextPDF держит память ровной, производя байты, в отличие от того, как читатель их получает потоком.
- Инкрементные обновления и зачем они нужны — почему позднейшая правка добавляется в конец и что это значит для вынесенной вперёд компоновки линеаризованного файла.
- Потоки и фильтры — что находится внутри объектов тела, на которые указывает таблица подсказок, и как они сжаты.
Глоссарий
Заголовок раздела «Глоссарий»- Линеаризация — пересборка, которая выносит вперёд первую страницу и навигационный индекс, чтобы программа просмотра могла отрисовывать и перемещаться до прихода всего файла. Так называется результат в стандарте.
- Fast Web View — потребительское название линеаризованного PDF; оба термина описывают один и тот же файл.
- Таблица подсказок — структура внутри линеаризованного файла, которая записывает диапазоны и расположения байтов каждой страницы и общих объектов, чтобы программа просмотра знала, какие срезы запрашивать; таблица перекрёстных ссылок — это то, что затем сопоставляет номеру объекта его точное смещение в байтах.
- Словарь параметров линеаризации — первый объект в линеаризованном файле; он объявляет ключевые смещения (длину первой страницы, расположение таблицы подсказок, основную позицию перекрёстных ссылок), которые делают возможным забор данных по запросу.
- Запрос диапазона байтов — HTTP-запрос среза файла, а не файла целиком; транспортный механизм, от которого зависит Fast Web View.
- Время до первой страницы — сколько проходит до того, как читатель увидит первую страницу. Задержка, которую оптимизирует линеаризация, отличная от общего времени загрузки.