Bhinish Dhiman· Actualizado 1 de octubre de 2026

Cuánto ahorra realmente la compresión de PDF sin pérdida, medido en once archivos

Traducido del original en inglés. Leer el original

La compresión de PDF sin pérdida, es decir, reempaquetar los objetos del archivo sin tocar el texto ni las imágenes, ahorró un 0.8% en un documento de texto impreso con Chromium, un 3.9% en un archivo de jsPDF (85.8% al comprimir los flujos sin filtro), un 6.5% en un archivo de macOS Quartz y menos de 0.05% en todo lo que tenía muchas imágenes, medido en once PDF. El único archivo que creció lo hizo en 7 bytes. El contenido de las páginas eliminadas sobrevivía al reempaquetado, así que ahora la herramienta reconstruye esos archivos.

Todos los compresores de PDF ofrecen una opción sin pérdida, y casi ninguno dice cuánto vale. Nosotros medimos la nuestra.

Dos términos, definidos

La compresión estructural consiste en reescribir cómo guarda un PDF sus objetos (la tabla de referencias cruzadas, el empaquetado de objetos pequeños en flujos, el filtro de compresión de cada flujo) sin alterar un solo glifo ni un solo píxel. Es el único tipo de compresión que se puede llamar sin pérdida con honestidad.

Un flujo de objetos es una función de PDF 1.5 que empaqueta muchos objetos pequeños (diccionarios de página, descriptores de fuente, anotaciones) en un solo flujo comprimido, en lugar de escribir cada uno sin comprimir. De ahí sale casi todo el ahorro estructural, y por eso el programa que generó el archivo decide el resultado antes de que el compresor se ejecute.

La medición

El 1 de octubre de 2026 generamos once PDF: las mismas veinte páginas de texto impresas con Chromium 153 (productor Skia/PDF m153), con macOS Quartz a través de cupsfilter, con jsPDF 4.2.1 y con pdf-lib con y sin flujos de objetos; diez fotografías de 1600 píxeles incrustadas con Chromium y con pdf-lib; cinco páginas tipo escaneo, cada una un JPEG en escala de grises a página completa con calidad 55; un documento de una línea y una página; un documento al que se le eliminaron cinco de sus diez páginas; y un archivo cifrado con AES-256. Cada uno pasó por compressStructural en src/lib/pdf/ops.ts, el código exacto detrás del ajuste sin pérdida de nuestro compresor, con Node 24 y @cantoo/pdf-lib 2.11.1.

Archivo Productor Antes Después Ahorro
20 páginas de texto Impresión de Chromium 82 109 B 81 426 B 0.8%
20 páginas de texto macOS Quartz 48 441 B 45 278 B 6.5%
20 páginas de texto jsPDF 4.2.1 72 814 B 69 977 B 3.9%
20 páginas de texto pdf-lib, sin flujos de objetos 34 041 B 33 168 B 2.6%
20 páginas de texto pdf-lib, con flujos de objetos 33 166 B 33 173 B −0.02%
10 fotografías Impresión de Chromium 1 528 699 B 1 528 112 B 0.04%
10 fotografías pdf-lib 1 509 614 B 1 508 973 B 0.04%
5 páginas escaneadas pdf-lib 1 816 323 B 1 815 924 B 0.02%
1 línea, 1 página pdf-lib 1 307 B 1 059 B 19.0%
10 páginas, 5 eliminadas pdf-lib 13 900 B 13 441 B 3.3%
Cifrado pdf-lib 2 940 B rechazado -

Cómo leer la tabla

Ninguno de los cuatro productores escribió flujos de objetos, y los cuatro escribieron una tabla clásica de referencias cruzadas. La pasada hace lo mismo con cada uno: reemplaza la tabla por un flujo de referencias cruzadas y empaqueta los objetos pequeños (diccionarios de página, descriptores de fuente, listas de recursos) en flujos de objetos. Así que el ahorro está limitado por los bytes que de entrada quedaban fuera de los flujos. En el archivo de Chromium eran 8 374 de 82 109 bytes, que bajaron a 6 896; en el de Quartz, 8 234 de 48,441, que bajaron a 4 224. Quartz es el que más ahorra porque escribió 71 objetos para veinte páginas, mientras que Chromium escribió 52, y con la tabla más extensa de los cuatro. El archivo de pdf-lib que ya tenía flujos de objetos salió 7 bytes más grande: ese es todo el caso de “tu archivo puede crecer” en esta muestra, y es la diferencia entre dos empaquetados igual de buenos de los mismos objetos.

El archivo de jsPDF muestra con más claridad el límite del método. jsPDF 4.2.1 escribe sus flujos de contenido sin comprimir de forma predeterminada: 65 255 de los 72 814 bytes del archivo son instrucciones de dibujo sin procesar, y zlib las reduce a 19 053. Es un 63.5% sin pérdida que estaba ahí, en el archivo. La pasada estructural no volvía a codificar un flujo existente, así que encontró un 3.9% y dejó en su lugar los 65 255 bytes sin comprimir. Una pasada que comprimiera los flujos sin filtro sería igual de sin pérdida (Flate devuelve exactamente los mismos bytes al decodificar), y con ese productor importaría dieciséis veces más que el reempaquetado.

Así que ahora el ajuste sin pérdida lo hace. Todo flujo escrito sin filtro se comprime y se conserva solo si el resultado es más pequeño; los flujos que ya tienen un filtro, como las imágenes JPEG, se dejan como están, y lo mismo pasa con los metadatos XMP, que según la especificación deben seguir siendo legibles para herramientas que no analizan PDF. Volvimos a medir con un documento comparable de jsPDF de veinte páginas: 132 980 bytes pasaron a 18,855, un ahorro del 85.8%, y el texto de cada página se podía seguir extrayendo del resultado.

En todo lo que tiene muchas imágenes, el ahorro es un error de redondeo, porque los bytes están en los flujos de imagen y una pasada estructural no los abre. Diez fotografías de 1.5 MB devolvieron 587 bytes. Cinco escaneos de 1.8 MB devolvieron 399 bytes. El 19% del documento de una línea son los mismos pocos cientos de bytes de sobrecarga de la tabla, en un archivo tan pequeño que esa sobrecarga es casi todo su contenido.

Las páginas eliminadas seguían ahí

El documento editado es el hallazgo que cambió cómo describimos este ajuste. Creamos diez páginas, cada una con un marcador único en el texto, eliminamos cinco y guardamos. El archivo guardado pesaba 13 900 bytes y todavía contenía los flujos de contenido de las diez páginas: las páginas eliminadas no tienen referencias, pero pdf-lib escribe todos los objetos que analizó. La pasada estructural reempaquetó ese archivo a 13 441 bytes con los diez marcadores todavía adentro, y la cantidad de objetos pasó de 19 a 21.

Copiar en cambio las cinco páginas vigentes a un documento nuevo produjo 7 518 bytes, un 46% menos que el resultado “comprimido”, con solo los marcadores del 0 al 4. Reempaquetar conserva los objetos huérfanos; reconstruir los descarta.

Eso importa para el tamaño, y todavía más para la privacidad: una página que eliminaste antes de enviar el archivo se podía seguir extrayendo de un archivo que había pasado por nuestro compresor sin pérdida. Peor aún, la propia descripción del ajuste decía que “drops unreferenced ones” (descarta los objetos sin referencias). No lo hacía.

Lo que cambiamos

Ahora el ajuste sin pérdida copia las páginas vigentes a un archivo nuevo siempre que sea seguro hacerlo, y conserva el resultado solo si es más pequeño. No siempre es seguro: los campos de formulario interactivos y el índice de marcadores pertenecen al documento y no a una página concreta, así que una reconstrucción los borraría sin avisar. Un archivo que tenga cualquiera de los dos solo se reempaqueta, y el resultado lo indica en lugar de dar a entender que los huérfanos desaparecieron.

Volvimos a medir después del cambio con un archivo comparable de diez páginas al que se le quitaron cinco: un reempaquetado simple dio 12 578 bytes con los diez marcadores adentro; la nueva pasada dio 9 211 bytes con solo los marcadores del 0 al 4, un 27% menos, y las páginas eliminadas desaparecieron de verdad. Una prueba en el repositorio ahora crea exactamente este archivo y falla si el contenido de una página eliminada sobrevive a la pasada.

Frente al método destructivo

Los otros dos ajustes de nuestra herramienta convierten cada página en un JPEG a 150 o 110 dpi y lo vuelven a incrustar. Eso reduce los escaneos muchísimo y convierte un documento de texto en imágenes de texto, sin selección, sin búsqueda y sin nada para un lector de pantalla. Los servicios genéricos logran un gran ahorro sin ese costo ejecutando Ghostscript en un servidor para reducir la resolución de las imágenes sin tocar la capa de texto; Ghostscript tiene licencia AGPL-3.0, y llevarlo al navegador pondría todo este sitio bajo esa licencia.

Así que la oferta honesta es lo que muestra la tabla: una pasada estructural que va a encontrar un pequeño porcentaje en un archivo de un productor antiguo y nada en uno moderno, o una pasada que rasteriza y te cuesta la capa de texto. Si el documento tiene campos de formulario o marcadores y quieres que el contenido eliminado desaparezca, la pasada sin pérdida no lo va a hacer por ti, y ahora lo dice: extrae las páginas que vas a conservar a un archivo nuevo, que es lo que hace Split PDF.