Ga naar inhoud
getnextpdf.com

Fast Web View: hoe een PDF opent voordat hij klaar is met downloaden

Spec: ISO 32000-2, Annex F

Een gelineariseerde PDF is zo geherorganiseerd dat de eerste pagina en een kleine navigatie-index helemaal vooraan in het bestand staan. Een viewer kan daardoor pagina één tekenen terwijl de rest van het document nog binnenkomt, en rechtstreeks naar pagina 147 springen zonder eerst de pagina’s 2 tot en met 146 te lezen.

Dit is de functie die de meeste lezers kennen onder haar vriendelijke naam: Fast Web View.

Stel je een rapport van 200 pagina’s voor op een telefoon met één streepje bereik. Zonder linearisatie heeft de viewer vaak het allerlaatste deel van het bestand nodig voordat hij iets kan tekenen, omdat de hoofdindex die aangeeft waar elk object zich bevindt traditioneel achteraan staat. Je kijkt dus naar een draaiend wieltje terwijl tweehonderd pagina’s downloaden, alleen om de eerste te lezen.

Met linearisatie is het bestand zo geordend dat het antwoord op “wat staat er op pagina één” als eerste van de lijn komt. De reader tekent pagina één in een seconde en haalt de rest pas op als je scrollt of springt. Op een snelle verbinding merk je het misschien nooit. Op een trage of betaald-per-MB verbinding is het het verschil tussen een bruikbaar document en een verlaten tabblad.

  • Een gelineariseerd bestand is front-loaded: pagina één en een hint-tabel worden eerst geplaatst, vóór de rest van de body.
  • De hint-tabel is een kaart van ranges. Hij vertelt de viewer welke byte-ranges bij elke pagina en bij de gedeelde objecten horen, zodat de viewer de server om precies die stukjes kan vragen — daarna lost de cross-reference-tabel elk objectnummer op naar de exacte offset.
  • Dit steunt op byte-range-requests — de viewer haalt stukjes van het bestand op aanvraag op, niet het geheel.
  • De bytes hebben qua inhoud dezelfde inhoud als een normale PDF. Linearisatie wijzigt de volgorde en de index, niet de pagina’s zelf.
  • Het is één expliciete, schakelbare stap in NextPDF — geproduceerd door een echte drietraps-herbouw, niet een vlag die op het beste hoopt.

Je kunt een pagina niet vooraan plaatsen totdat je precies weet hoe groot alles is, want de hint-tabel legt byte-offsets vast en een offset is pas correct als de lengte van elk object definitief is. Die circulariteit — offsets hangen af van groottes, groottes hangen af van layout — is de reden dat een linearizer in fasen draait in plaats van in één veeg.

NextPDF lost dit op met een deterministische drietraps-herbouw. De eerste fase meet, de tweede beslist over plaatsing, de derde schrijft de echte bytes met de nu bekende offsets ingebakken.

  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.
De drietraps linearisatie-herbouw. MEASURE bepaalt de grootte van elk object zodat lengtes definitief zijn; PLACE beslist de front-loaded volgorde en reserveert de regio voor de hint-tabel; FILL schrijft de echte bytes met de nu bekende offsets, zodat de eerste pagina en de hint-tabel vooraan landen en de cross-reference-gegevens bij de eerste fetch oplosbaar zijn.

De uitvoer draagt een linearization parameter dictionary als zijn eerste object en een of meer hint-tabellen die de pagina’s indexeren, precies zoals de standaard voorschrijft (Spec: ISO 32000-2, Annex F). Die hint-tabellen werken naast een traditionele cross-reference-tabel — zij leggen de byte-ranges en locaties vast die een viewer moet ophalen, terwijl de cross-reference-tabel de index is die elk objectnummer op zijn exacte byte-offset afbeeldt. NextPDF’s linearizer levert de klassieke tabelvorm en verwijdert onderweg elke cross-reference stream, zodat de reader zodra een stukje binnenkomt een object oplost via zijn offset rechtstreeks uit die tabel (Spec: ISO 32000-2, §7.5.4).

Een handig mentaal model: een normale PDF is een boek waarvan de inhoudsopgave aan de achterkaft is gelijmd. Een gelineariseerde PDF verplaatst die inhoudspagina naar voren en voegt een index per pagina met paginanummers toe, zodat je rechtstreeks elke pagina kunt openen. De hoofdstukken zijn ongewijzigd. Alleen de navigatie is verplaatst.

Linearisatie is een expliciete, schakelbare stap. Je vraagt erom; de engine voert de herbouw uit en levert een Fast-Web-View-bestand.

<?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);

De pagina-inhoud is precies wat je hebt geschreven. Het verschil zit in de bestandsvolgorde van de bytes die je ontvangt, en in de hint-tabel die nu boven aan staat.

Je controleert het resultaat zoals een vreemde dat zou doen — met een externe checker:

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

qpdf --check-linearization zoekt niet alleen naar een vlag. Het leidt de offsets die het bestand beweert opnieuw af en bevestigt dat ze kloppen: dat de objecten van de eerste pagina echt staan waar de linearization dictionary zegt, dat de hint-tabel naar de juiste bytes wijst en dat de structuur voldoet aan Annex F. Een bestand dat liegt over zijn eigen layout zakt voor deze controle, zelfs als het op het eerste gezicht gelineariseerd lijkt.

De veelgehoorde aanname is dat linearisatie het bestand comprimeert of de download in het algemeen sneller maakt. Het doet geen van beide. Een gelineariseerd bestand is vaak een paar bytes groter, omdat het de extra hint-tabellen meedraagt. De totale overdrachtstijd voor het hele document is in wezen ongewijzigd.

Wat verandert, is wanneer de eerste bruikbare pixel verschijnt. Linearisatie optimaliseert time-to-first-page, niet de totale bytes. Het is een latency-functie, geen compressiefunctie. Pagina één vroeg streamen en het bestand snel downloaden zijn verschillende doelen, en linearisatie dient het eerste.

Een tweede misverstand is dat elke webserver een gelineariseerd bestand zal streamen. De viewer moet byte-ranges ophalen, wat betekent dat de server HTTP range-requests moet honoreren. De meeste doen dat, maar een server die altijd het hele bestand teruggeeft, maakt van Fast Web View weer een trage wachttijd op het hele bestand — het bestand is klaar om te streamen, maar het transport niet.

NextPDF heeft volledige core-ondersteuning voor het produceren van gelineariseerde bestanden: een productiewaardige drietraps-linearizer die de parameter dictionary en hint-tabellen levert en slaagt voor een externe Annex F-controle.

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

Twee grenzen zijn het benoemen waard. Ten eerste is linearisatie een eigenschap van één revisie. Op het moment dat je een incrementele update toevoegt — een handtekening, een formulierinvulling, een bewerking — gaan de toegevoegde bytes aan het einde en is het bestand niet langer strikt gelineariseerd totdat het opnieuw wordt gebouwd. Dat is een normale afweging, geen defect; zie incrementele updates voor waarom toevoegen het juiste gedrag is voor ondertekende documenten.

Ten tweede beheert de engine het bestand. Hij beheert het netwerk niet. Fast Web View levert zijn belofte alleen waar de serverende verbinding byte-range-requests honoreert; de bytes kunnen perfect gelineariseerd zijn en toch als één trage klomp binnenkomen als de server erop staat het hele bestand te versturen.

  • De anatomie van een PDF-bestand — de header, body, cross-reference-tabel en trailer die linearisatie herschikt. Lees dit eerst om te zien wat er wordt herordend.
  • Geheugen en streaming — streaming aan de schrijfkant, een andere as: hoe NextPDF het geheugengebruik vlak houdt tijdens het produceren van bytes, versus hoe een reader ze binnenstreamt.
  • Incrementele updates en waarom ze ertoe doen — waarom een latere bewerking aan het einde wordt toegevoegd, en wat dat betekent voor de front-loaded layout van een gelineariseerd bestand.
  • Streams en filters — wat er zit in de body-objecten waar de hint-tabel naar wijst, en hoe ze worden gecomprimeerd.
  • Linearisatie — de herbouw die de eerste pagina en een navigatie-index vooraan plaatst zodat een viewer kan renderen en navigeren voordat het hele bestand is binnengekomen. De naam die de standaard aan het resultaat geeft.
  • Fast Web View — de naam richting de consument voor een gelineariseerde PDF; de twee termen beschrijven hetzelfde bestand.
  • Hint-tabel — de structuur binnen een gelineariseerd bestand die de byte-ranges en locaties van elke pagina en de gedeelde objecten vastlegt, zodat een viewer weet welke stukjes hij moet opvragen; de cross-reference-tabel is wat vervolgens een objectnummer op zijn exacte byte-offset afbeeldt.
  • Linearization parameter dictionary — het eerste object in een gelineariseerd bestand; het declareert de belangrijke offsets (lengte van de eerste pagina, locatie van de hint-tabel, positie van de hoofd-cross-reference) die ophalen op aanvraag mogelijk maken.
  • Byte-range-request — een HTTP-request voor een stukje van een bestand in plaats van het geheel; het transportmechanisme waar Fast Web View van afhangt.
  • Time-to-first-page — hoe lang het duurt voordat een lezer pagina één ziet. De latency die linearisatie optimaliseert, te onderscheiden van de totale downloadtijd.