Pon un informe escaneado de 80 MB detrás de un enlace, ábrelo en un navegador y observa qué ocurre: el visualizador permanece en un panel en blanco hasta que llega una gran parte de esos bytes y entonces pinta la primera página de golpe. Saltar a la página 40 puede, en un fichero mal construido, reiniciar la descarga completa. Lo frustrante es que el lector solo quería la primera página. La linealización es la respuesta estructural a ese problema. Reorganiza un PDF para que un visualizador pueda renderizar la página inicial a partir de un pequeño prefijo del fichero y obtener el resto bajo demanda, que es por eso que Adobe comercializa esta función como "Fast Web View".
Nada de esto supone un formato de fichero diferente. Un PDF linealizado es un PDF ordinario que un lector conforme abrirá sin ningún tratamiento especial. El truco reside enteramente en cómo se ordenan los bytes y en dos estructuras adicionales que lleva el fichero. ISO 32000-1 especifica toda la disposición en el Anexo F, y una vez que se comprende el diseño, el comportamiento deja de parecer magia y empieza a verse como un intercambio deliberado entre el orden del fichero y la latencia del primer renderizado.
Qué reorganiza realmente la linealización
Un PDF normal puede dispersar sus objetos en casi cualquier orden. La tabla de referencias cruzadas al final del fichero es lo que lo hace posible: un lector busca al final, lee el puntero startxref, carga la xref y desde ahí puede localizar cada objeto por su desplazamiento. Ese diseño es excelente para ficheros locales, donde ir al final no tiene coste, y deficiente para un fichero que llega por la red, donde el final es exactamente la parte que llega en último lugar. Para renderizar la primera página, un lector convencional necesita el objeto de página, su flujo de contenido, las fuentes a las que hace referencia y las imágenes que dibuja, y en un fichero desordenado estos pueden estar en cualquier lugar, incluso en el último megabyte.
La linealización corrige el orden. Los objetos necesarios para mostrar la primera página se agrupan en un bloque contiguo cerca del principio, justo después de una pequeña sección de cabecera, para que lleguen al principio del flujo de bytes. Todo lo demás, las páginas restantes y los recursos que comparten, sigue en una secuencia predecible. Una segunda tabla de referencias cruzadas completa sigue residiendo al final para los lectores que ignoran la optimización, pero un fichero linealizado también coloca al principio una referencia cruzada de primera página y los parámetros que necesita un lector de flujo. El lector ya no tiene que llegar al final antes de poder dibujar nada.
El conjunto de objetos de primera página y el diccionario de parámetros de linealización
El primer objeto de un fichero linealizado, tras la cabecera %PDF, es el diccionario de parámetros de linealización. Es lo que busca un lector de flujo para decidir si la optimización está presente y cómo usarla. El diccionario registra la longitud total del fichero, el desplazamiento en bytes donde comienza la sección principal de referencias cruzadas, el número de objeto de la primera página y la ubicación y longitud del hint stream que sigue. Con esos datos, un lector sabe, a partir de los primeros kilobytes, cuánto debe descargar para mostrar la primera página y dónde buscar el índice que le permite saltar a otra parte.
El Anexo F es estricto respecto a lo que significa "primera página" aquí. La sección de primera página debe contener el propio objeto de página, sus flujos de contenido y los recursos a los que hacen referencia esos flujos, de modo que la página sea autosuficiente una vez descargado ese prefijo. Los recursos compartidos, una fuente usada en todas las páginas o un logotipo que se repite en una cabecera, se tratan de forma especial: aparecen lo suficientemente pronto para servir a la primera página pero se marcan como compartidos para que el lector no los vuelva a descargar al renderizar la página 30. La distinción entre objetos privados de página y objetos compartidos es la parte que la mayoría de los "optimizadores" caseros implementan mal, y ese error es el que produce ficheros que dicen estar linealizados pero que siguen atascándose.
Hint streams: el índice que hace baratos los saltos de página
Mostrar la primera página rápidamente es solo la mitad del valor. La otra mitad es saltar a una página arbitraria sin descargar todo lo que hay entre medio, y eso es lo que proporcionan los hint streams. Un fichero linealizado lleva una tabla de desplazamientos de página y una tabla de objetos compartidos, almacenadas como un flujo referenciado desde el diccionario de parámetros. La tabla de desplazamientos de página registra, para cada página, dónde comienzan sus objetos en el fichero y cuánto ocupan. La tabla de objetos compartidos hace lo mismo para los recursos usados en varias páginas.
Con esas tablas, un lector que quiere la página 40 no analiza el fichero de forma secuencial. Consulta la tabla de hints para conocer el rango de bytes que ocupa la página 40, solicita al servidor exactamente ese rango y renderiza la página cuando llegan esos bytes, obteniendo los recursos compartidos que aún no tiene mediante el mismo mecanismo. El hint stream es, en efecto, un mapa de acceso aleatorio superpuesto al documento, y es la razón por la que un fichero de 500 páginas bien linealizado se siente ágil en una conexión lenta mientras que uno sin optimizar del mismo tamaño no lo hace.
Por qué el servidor debe cooperar
La linealización asume que el transporte puede entregar fragmentos arbitrarios del fichero, y esa suposición vale la pena verificarla antes de culpar al formato por resultados deficientes. El mecanismo es la entrega por rangos HTTP: el lector emite peticiones de rango y el servidor responde con respuestas 206 Partial Content. Si el servidor no anuncia Accept-Ranges: bytes, o si un proxy o CDN delante de él convierte las peticiones de rango en transferencias completas, el lector no tiene forma de obtener la página 40 de forma aislada y recurre a descargar el fichero completo. La estructura dentro del PDF entonces es perfectamente correcta y completamente inútil.
Este es el fallo que con más frecuencia se diagnostica erróneamente como "la linealización no funciona". El fichero está bien; la vía de entrega no lo está. Antes de reconstruir un documento, confirma con una petición condicional que el servidor devuelve realmente contenido parcial para la URL que visita el lector. Muchos servidores estáticos hacen esto por defecto, y muchos servidores de aplicaciones mal configurados y capas de caché no lo hacen.
Las actualizaciones incrementales rompen silenciosamente la linealización
Esta es la restricción que sorprende a quienes generan ficheros linealizados correctamente y luego se preguntan por qué desaparece la optimización. La linealización depende de un diseño cuidadosamente ordenado con su índice al principio. Una actualización incremental viola eso por diseño. Cuando una herramienta añade una firma, rellena un campo de formulario o añade una anotación mediante un guardado incremental, no reescribe el fichero. Añade los objetos modificados, una nueva sección de referencias cruzadas y un nuevo tráiler al final, dejando los bytes originales intactos. Ese añadido es el objetivo de las actualizaciones incrementales: es rápido y conserva la revisión anterior para auditoría o validación de firma.
El efecto secundario es que el fichero ahora tiene sus datos de referencias cruzadas más recientes al final, después del bloque de primera página cuidadosamente colocado, y el diccionario de parámetros de linealización al principio describe un diseño que ya no coincide con el fichero. Un lector conforme detecta la discrepancia y trata el documento como un PDF normal no linealizado. Fast Web View ha desaparecido, aunque la estructura linealizada original sigue estando en la primera mitad del fichero. Si se añaden varias actualizaciones, cada una apila otra revisión al final y la brecha entre el índice frontal obsoleto y el estado real se amplía.
Si el flujo de trabajo necesita tanto ediciones como Fast Web View, la regla se deduce directamente de la estructura: editar de forma incremental mientras el documento está en proceso y luego relinealizar una sola vez al final. Una reescritura completa es lo que restaura el diseño. En términos de HotPDF, eso significa que una edición en curso pasa por BeginIncrementalUpdate y SaveIncrementalUpdate, que añaden un delta, mientras que el paso final carga el documento completo y lo serializa de nuevo con LoadFromFile seguido de SaveLoadedDocument, que descarta las revisiones antiguas acumuladas y emite un diseño limpio. El mismo compromiso aparece con los flujos de objetos: habilitar UseObjectStreams junto con UseXRefStream comprime las referencias cruzadas y empaqueta los objetos de forma compacta, lo que ayuda al tamaño del fichero pero, como cualquier elección estructural, debe aplicarse durante esa reescritura final y no añadirse encima de una revisión ya añadida.
// In-flight edits: append a delta, keep prior revisions intact.
// This leaves the file NOT linearized.
Pdf.BeginIncrementalUpdate('report.pdf');
Pdf.AddPage;
Pdf.CurrentPage.TextOut(72, 760, 0, 'Addendum');
Pdf.SaveIncrementalUpdate('report.pdf');
// Finishing step: full re-serialization produces one clean layout,
// dropping the stacked revisions. Re-run your linearizer on the output.
Pdf.LoadFromFile('report.pdf');
Pdf.SaveLoadedDocument('report-final.pdf');
HotPDF no expone una rutina "linearize" de una sola llamada, por lo que el patrón práctico es producir un fichero limpio y completamente reescrito y pasar por un optimizador dedicado. Las herramientas de línea de comandos gestionan la reorganización directamente. qpdf reescribe un fichero en forma linealizada con un único indicador:
qpdf --linearize report-final.pdf report-web.pdf
Cómo saber si un fichero está linealizado
No confíes en el nombre del fichero ni en la herramienta que afirma haberlo producido; verifica los bytes. La comprobación más directa es el inicio del fichero: ábrelo y busca el diccionario de parámetros de linealización como primer objeto tras la cabecera, con la clave /Linearized. Un acceso directo para el usuario es el cuadro de diálogo Propiedades del documento de Acrobat, que reporta "Fast Web View: Sí" solo cuando la estructura está genuinamente presente y vigente.
Para comprobaciones automatizadas, qpdf informa tanto de la presencia como de la integridad de la estructura, lo que importa porque un fichero puede llevar un diccionario de linealización que ya no refleja su diseño, exactamente el estado que deja una actualización incremental:
# Reports "File is linearized" and validates hint tables against the layout
qpdf --check report-web.pdf
# Dumps the linearization parameters and hint data in detail
qpdf --show-linearization report-web.pdf
El paso de validación es el que verdaderamente vale la pena. Una comprobación que solo confirma que existe el diccionario bendecirá alegremente un fichero cuyo índice apunta a desplazamientos incorrectos; una comprobación que reconcilia las tablas de hints con las posiciones reales de los objetos es la que indica si la optimización aguantará las peticiones de rango de un lector real.
La linealización sigue mereciendo la pena aplicarla a cualquier documento grande servido por la web, especialmente para lectores móviles con conexiones inestables, y tiene un coste de unos pocos puntos porcentuales en tamaño de fichero por el índice adelantado. Los dos aspectos que hay que tener claros son que tanto la estructura dentro del PDF como la entrega por bytes fuera de él deben ser correctas, y que cualquier edición posterior deshace la optimización hasta que se reescriba el fichero. Trata la relinealización como el último paso del proceso, después de que todos los demás cambios estén resueltos. El comportamiento de referencias cruzadas, flujos de objetos y actualizaciones incrementales descrito aquí forma parte del modelo estructural que implementa el HotPDF Component para Delphi y C++Builder; para el contexto más amplio del diseño del fichero, consulta cómo está estructurado un PDF, y para el flujo de trabajo con actualizaciones incrementales y ficheros grandes en código, consulta procesamiento de PDF de gran tamaño desde Delphi.