Placez un rapport scanné de 80 Mo derrière un lien, ouvrez-le dans un navigateur et regardez ce qui se passe : le visualiseur reste sur un volet blanc jusqu'à ce qu'une grande partie de ces octets soit arrivée, puis affiche la page une d'un seul coup. Sautez à la page 40 et, sur un fichier mal construit, tout le téléchargement peut repartir de zéro. Le plus frustrant, c'est que le lecteur ne voulait que la première page. La linéarisation est la réponse structurelle à ce problème. Elle réorganise un PDF pour qu'un visualiseur puisse rendre la page d'ouverture à partir d'un petit préfixe du fichier et récupérer le reste à la demande, ce qui explique pourquoi Adobe commercialise la fonction sous le nom de « Fast Web View »
Rien de tout cela n'est un format de fichier différent. Un PDF linéarisé est un PDF ordinaire qu'un lecteur conforme ouvrira sans traitement particulier. L'astuce tient entièrement à l'ordre des octets et à deux structures supplémentaires que le fichier transporte. La norme ISO 32000-1 spécifie tout l'agencement dans son annexe F, et une fois la disposition vue, le comportement cesse de ressembler à de la magie et devient un échange délibéré entre l'ordre du fichier et la latence du premier affichage
Ce que la linéarisation réorganise réellement
Un PDF normal peut disperser ses objets dans presque n'importe quel ordre. La table de références croisées placée à la fin du fichier est ce qui rend cela possible : un lecteur se place à la fin, lit le pointeur startxref, charge la xref et peut dès lors localiser chaque objet par son décalage. Cette conception est excellente pour les fichiers locaux, où atteindre la fin ne coûte rien, et mauvaise pour un fichier qui arrive en flux sur un réseau, où la fin est précisément la partie qui arrive en dernier. Pour rendre la page une, un lecteur classique a besoin de l'objet page, de son flux de contenu, des polices qu'il référence et des images qu'il dessine, et dans un fichier non ordonné ceux-ci peuvent se trouver n'importe où, y compris dans le dernier mégaoctet
La linéarisation corrige l'ordre. Les objets nécessaires à l'affichage de la première page sont rassemblés en un bloc contigu près du début, juste après une petite section d'en-tête, si bien qu'ils arrivent tôt dans le flux d'octets. Tout le reste, les pages restantes et les ressources qu'elles partagent, suit dans un ordre prévisible. Une seconde table de références croisées complète reste à la fin pour les lecteurs qui ignorent l'optimisation, mais un fichier linéarisé place aussi en tête une table de références croisées de première page et les paramètres dont un lecteur en flux a besoin. Le lecteur n'a plus à atteindre la queue avant de pouvoir dessiner quoi que ce soit
L'ensemble d'objets de première page et le dictionnaire de paramètres de linéarisation
Le tout premier objet d'un fichier linéarisé, après l'en-tête %PDF, est le dictionnaire de paramètres de linéarisation. C'est ce qu'un lecteur en flux cherche pour décider si l'optimisation est présente et comment l'utiliser. Le dictionnaire enregistre la longueur du fichier entier, le décalage d'octet où commence la section principale de références croisées, le numéro d'objet de la première page, ainsi que l'emplacement et la longueur du flux de hints qui suit. Avec ces nombres, un lecteur sait, à partir des seuls kilo-octets d'ouverture, combien il doit récupérer pour afficher la page une et où chercher l'index qui lui permet de sauter ailleurs
L'annexe F est stricte sur ce que « première page » signifie ici. La section de première page doit contenir l'objet page lui-même, ses flux de contenu et les ressources que ces flux référencent, afin que la page se suffise à elle-même une fois ce préfixe téléchargé. Les ressources partagées, une police utilisée sur chaque page, un logo qui se répète dans un en-tête, sont traitées à part : elles apparaissent assez tôt pour servir la première page mais sont marquées comme partagées, de sorte que le lecteur ne les récupère pas de nouveau lorsqu'il rendra plus tard la page 30. Cette distinction entre objets privés à une page et objets partagés est la partie que la plupart des « optimiseurs » maison ratent, et la rater produit un fichier qui se déclare linéarisé mais bloque quand même
Les flux de hints : l'index qui rend les sauts de page peu coûteux
Afficher vite la page une n'est que la moitié de la valeur. L'autre moitié consiste à sauter à une page arbitraire sans télécharger tout ce qui se trouve entre les deux, et c'est ce que fournissent les flux de hints. Un fichier linéarisé transporte une table de hints des décalages de page et une table de hints des objets partagés, stockées sous forme de flux référencé depuis le dictionnaire de paramètres. La table des décalages de page enregistre, pour chaque page, où commencent ses objets dans le fichier et sur quelle longueur ils s'étendent. La table des objets partagés fait de même pour les ressources utilisées sur plusieurs pages
Avec ces tables, un lecteur qui veut la page 40 n'analyse pas le fichier de façon séquentielle. Il consulte la table de hints pour connaître la plage d'octets qu'occupe la page 40, demande au serveur exactement cette plage et rend la page dès que ces octets arrivent, en tirant par le même mécanisme toute ressource partagée qu'il ne détient pas déjà. Le flux de hints est, en pratique, une carte d'accès aléatoire posée sur le document, et c'est la raison pour laquelle un fichier de 500 pages bien linéarisé paraît réactif sur un lien lent alors qu'un fichier non optimisé de même taille ne l'est pas
Pourquoi le serveur doit coopérer
La linéarisation suppose que le transport peut livrer des tranches arbitraires du fichier, et cette hypothèse mérite d'être vérifiée avant d'imputer au format de mauvais résultats. Le mécanisme est le byte-serving HTTP : le lecteur émet des requêtes de plage, et le serveur y répond par des réponses 206 Partial Content. Si le serveur n'annonce pas Accept-Ranges: bytes, ou si un proxy ou un CDN placé devant lui convertit les requêtes de plage en transferts complets, le lecteur n'a aucun moyen de récupérer la page 40 isolément et se rabat sur le téléchargement du fichier entier. La structure interne du PDF est alors parfaitement correcte et entièrement gâchée
C'est l'échec le plus souvent mal diagnostiqué en « la linéarisation ne fonctionne pas ». Le fichier va bien ; c'est le chemin de livraison qui ne va pas. Avant de reconstruire un document, confirmez par une requête conditionnelle que l'hôte renvoie réellement du contenu partiel pour l'URL que le lecteur atteint. Beaucoup d'hébergeurs statiques le font par défaut, et beaucoup de serveurs applicatifs et de couches de cache mal configurés ne le font pas
Les mises à jour incrémentielles cassent discrètement la linéarisation
Voici la contrainte qui surprend ceux qui produisent correctement des fichiers linéarisés puis se demandent pourquoi l'optimisation s'évapore. La linéarisation dépend d'une disposition unique et soigneusement ordonnée, avec son index en tête. Une mise à jour incrémentielle viole cela par conception. Quand un outil ajoute une signature, remplit un champ de formulaire ou ajoute une annotation par une sauvegarde incrémentielle, il ne réécrit pas le fichier. Il ajoute à la fin les objets modifiés, une nouvelle section de références croisées et un nouveau trailer, en laissant les octets d'origine intacts. Cet ajout est tout l'intérêt des mises à jour incrémentielles : il est rapide, et il préserve la révision antérieure pour l'audit ou la validation de signature
L'effet de bord est que le fichier possède désormais ses données de références croisées les plus récentes en queue, après le bloc de première page soigneusement placé, tandis que le dictionnaire de paramètres de linéarisation en tête décrit une disposition qui ne correspond plus au fichier. Un lecteur conforme détecte l'incohérence et traite le document comme un PDF normal, non linéarisé. Le Fast Web View a disparu, même si la structure linéarisée d'origine est toujours là, dans la première moitié du fichier. Si vous ajoutez plusieurs mises à jour, chacune empile une révision de plus à la fin et l'écart entre l'index de tête périmé et l'état réel se creuse
Si votre flux de travail a besoin à la fois de modifications et du Fast Web View, la règle découle directement de la structure : modifiez de façon incrémentielle tant que le document évolue, puis relinéarisez une seule fois à la fin. Une réécriture complète est ce qui restaure la disposition. En termes HotPDF, cela signifie qu'une modification en cours passe par BeginIncrementalUpdate et SaveIncrementalUpdate, qui ajoutent un delta, tandis que l'étape finale charge tout le document et le sérialise à neuf avec LoadFromFile suivi de SaveLoadedDocument, ce qui abandonne les anciennes révisions accumulées et émet une seule disposition propre. Le même arbitrage apparaît avec les flux d'objets : activer UseObjectStreams avec UseXRefStream compresse les références croisées et tasse les objets, ce qui aide la taille du fichier mais, comme tout choix structurel, doit être appliqué pendant cette réécriture finale plutôt que greffé sur une révision ajoutée
// Modifications en cours : ajoute un delta, conserve intactes les révisions antérieures.
// Cela laisse le fichier NON linéarisé.
Pdf.BeginIncrementalUpdate('report.pdf');
Pdf.AddPage;
Pdf.CurrentPage.TextOut(72, 760, 0, 'Addendum');
Pdf.SaveIncrementalUpdate('report.pdf');
// Étape finale : la resérialisation complète produit une disposition propre,
// en abandonnant les révisions empilées. Relancez votre linéariseur sur la sortie.
Pdf.LoadFromFile('report.pdf');
Pdf.SaveLoadedDocument('report-final.pdf');
HotPDF n'expose pas de routine « linéariser » en un seul appel : le schéma pratique consiste donc à produire un fichier propre et entièrement réécrit, puis à lui appliquer un optimiseur dédié. Les outils en ligne de commande gèrent directement la réorganisation. qpdf réécrit un fichier sous forme linéarisée avec un seul indicateur :
qpdf --linearize report-final.pdf report-web.pdf
Comment savoir si un fichier est linéarisé
Ne faites confiance ni au nom du fichier ni à l'outil qui prétend l'avoir produit ; vérifiez les octets. Le contrôle le plus direct porte sur la tête du fichier : ouvrez-la et cherchez le dictionnaire de paramètres de linéarisation comme premier objet après l'en-tête, portant la clé /Linearized. Un raccourci côté lecteur est la boîte de dialogue Propriétés du document d'Acrobat, qui indique « Fast Web View : Oui » seulement lorsque la structure est réellement présente et à jour
Pour des contrôles scriptés, qpdf signale à la fois la présence et l'intégrité de la structure, ce qui compte parce qu'un fichier peut porter un dictionnaire de linéarisation qui ne reflète plus sa disposition, précisément l'état que laisse une mise à jour incrémentielle :
# Signale "File is linearized" et valide les hint tables face à la mise en page
qpdf --check report-web.pdf
# Dump en détail les paramètres de linéarisation et les données de hint
qpdf --show-linearization report-web.pdf
L'étape de validation est celle qui vaut son prix. Un contrôle qui se contente de confirmer l'existence du dictionnaire bénira volontiers un fichier dont l'index pointe vers de mauvais décalages ; un contrôle qui rapproche les tables de hints des positions réelles des objets est celui qui vous dit que l'optimisation tiendra face aux requêtes de plage d'un vrai lecteur
La linéarisation reste utile pour tout document volumineux servi sur le web, en particulier pour les lecteurs mobiles sur des connexions inégales, et elle coûte quelques pour cent de taille de fichier pour l'index placé en tête. Les deux points à garder clairs sont que la structure interne du PDF et le byte-serving à l'extérieur doivent tous deux être corrects, et que toute modification après coup annule l'optimisation jusqu'à ce que vous réécriviez le fichier. Traitez la relinéarisation comme la dernière étape de la chaîne, une fois tous les autres changements figés. Le comportement des références croisées, des flux d'objets et des mises à jour incrémentielles décrit ici fait partie du modèle structurel qu'implémente le composant HotPDF pour Delphi destiné à Delphi et C++Builder ; pour le contexte plus large de la disposition des fichiers, voyez comment un PDF est structuré, et pour le flux de mise à jour incrémentielle et de gros fichiers en code, voyez le traitement de gros PDF depuis Delphi