¿Qué es el renderizado progresivo?
El renderizado progresivo presenta partes utilizables o versiones cada vez más completas del contenido a medida que los datos están disponibles. Evita retener el resultado completo hasta que hayan terminado todos los recursos o etapas de procesamiento.
Cómo funciona el renderizado progresivo
El renderizado progresivo es una estrategia que abarca el encoding, el transporte, el análisis y la presentación; no es un único formato multimedia. En el nivel del archivo, un JPEG progresivo almacena la imagen como una serie de barridos de calidad creciente, por lo que un decodificador puede mostrar una versión aproximada de toda la imagen desde el primer barrido y perfeccionarla a medida que llegan más, y un PNG entrelazado transmite sus píxeles en siete pasadas. En el nivel del documento, un servidor puede transmitir HTML de forma continua para que el navegador muestre la estructura externa de la página y los marcadores de posición mientras aún se producen las secciones más lentas; el renderizador de servidor de React con transmisión continua, por ejemplo, envía primero el contenido alternativo de un límite <Suspense> y después el contenido real. Los dos niveles abordan esperas diferentes: el desglose de Largest Contentful Paint de web.dev cuenta el tiempo hasta el primer byte del documento HTML y el tiempo de carga del propio recurso de imagen como componentes separados, por lo que enviar el documento antes no acorta la descarga de una imagen a la que hace referencia, aunque el navegador puede iniciar esa descarga antes si el HTML que llega primero ya contiene la URL de la imagen. En ambos casos, el resultado anticipado solo ayuda si realmente llega pronto a la pantalla; reservar espacio para el resultado final evita que el reemplazo desplace los elementos circundantes del diseño.
Datos clave
- ¿Qué formatos de imagen pueden renderizarse progresivamente? JPEG cuando se procesa con encoding en modo progresivo, PNG y GIF cuando están entrelazados, y JPEG XL, aunque MDN señala que Safari renderiza JPEG XL solo después de la descarga completa. WebP no puede perfeccionar una vista previa de toda la imagen: las preguntas frecuentes de WebP de Google indican que no ofrece actualización progresiva ni entrelazada en el sentido de JPEG o PNG, solo decodificación incremental que muestra filas a medida que llegan sus bytes. En AVIF depende del encoding y del visor. La especificación AVIF admite la decodificación progresiva mediante imágenes en capas, pero permite que el renderizador muestre solo la capa superior;
avifencde libavif produce un archivo de este tipo con--progressive, y el registro de cambios de libavif menciona Chrome como un visor que renderiza las capas progresivamente. La guía de formatos de MDN, en cambio, afirma que AVIF no admite el renderizado progresivo y que los archivos deben descargarse por completo antes de mostrarse; añade que el menor tamaño de los archivos AVIF suele compensarlo, salvo en los archivos más grandes. Por tanto, convertir a WebP o AVIF no conserva por sí solo el efecto de mostrar primero una versión aproximada: para AVIF, comprueba la configuración del codificador y los navegadores de destino; de lo contrario, un marcador de posición independiente tiene que proporcionar ese efecto. - ¿Qué costo tiene un JPEG progresivo? Principalmente trabajo de decodificación, no tamaño de archivo. La documentación de libjpeg indica que los archivos progresivos suelen ser ligeramente más pequeños que los secuenciales de la misma calidad y que la imagen final es idéntica. También indica que decodificar cada barrido mostrado requiere aproximadamente tanto trabajo como decodificar una imagen completa del mismo tamaño, y que los barridos intermedios solo se muestran si la aplicación usa el modo de imagen con búfer de la biblioteca; de lo contrario, el decodificador lee todos los barridos y devuelve únicamente la imagen final. Por tanto, que los usuarios vean el perfeccionamiento depende del decodificador utilizado, no solo del archivo.
- ¿Por qué una página transmitida de forma continua sigue apareciendo de una sola vez? Por lo general, algo entre el renderizador y el navegador está reteniendo los bytes. nginx almacena por defecto en búfer las respuestas que pasan por el proxy y solo transmite los datos a medida que los recibe cuando
proxy_bufferingestá desactivado o el servidor de origen envíaX-Accel-Buffering: no, un encabezado que se puede indicar a nginx que ignore medianteproxy_ignore_headers; la guía de alojamiento propio de Next.js añade que algunos balanceadores de carga en la nube almacenan las respuestas en búfer de forma predeterminada y que los proxies inversos entre el balanceador de carga y la aplicación también deben transmitir las respuestas fragmentadas sin almacenarlas en búfer. La compresión almacena una ventana de datos de salida en búfer para comprimirlos eficazmente; el README decompressionde Express describe este comportamiento para los eventos enviados por el servidor y proporcionares.flush()para forzar el envío de la respuesta parcialmente comprimida al cliente. La propia aplicación puede anular el efecto: React documenta que iniciar la transmisión enonAllReadyen lugar deonShellReadyno ofrece carga progresiva. Incluso cuando los bytes llegan pronto, el CSS o JavaScript cargado al inicio puede seguir bloqueando el renderizado. - ¿La carga progresiva provoca desplazamientos del diseño? Puede provocarlos cuando no se reserva el espacio para el contenido que llega más tarde. La guía de Google sobre Cumulative Layout Shift incluye las imágenes sin dimensiones y el contenido insertado dinámicamente entre las causas más comunes de una mala puntuación, e indica que siempre se deben establecer
widthyheighten las imágenes y el video o reservar el espacio conaspect-ratiode CSS. Una imagen que se perfecciona dentro de un recuadro de tamaño conocido no desplaza nada a su alrededor; un reemplazo cuyo tamaño difiere del de su marcador de posición puede desplazar el contenido circundante, a menos que un contenedor ya reserve el espacio.
Cuándo es importante el renderizado progresivo
Diseña para el renderizado progresivo cuando se pueda dar prioridad al contenido significativo de la página o del material multimedia frente a los detalles secundarios. En cambio, las dimensiones inestables o las actualizaciones mal ordenadas pueden provocar desplazamientos del diseño y cambios visuales que distraen.
Cómo ayuda Transloadit con el renderizado progresivo
El Robot /image/resize de Transloadit tiene un parámetro progressive que entrelaza la salida para que los navegadores puedan mostrar primero una versión de baja resolución de toda la imagen; está desactivado de forma predeterminada. En los formatos en los que esto no se aplica, un Step que produce una imagen puede extraer un BlurHash o ThumbHash mediante output_meta, un marcador de posición compacto que se muestra mientras se carga la imagen completa. Los resultados de imagen en la respuesta de Assembly Status también incluyen width, height y aspect_ratio en sus metadatos, que es lo que necesita una página para reservar el recuadro de la imagen antes de que llegue.
La documentación del Robot indica un aumento del tamaño de archivo para progressive sin especificar a qué formatos de salida se aplica, lo que difiere de lo que dice la documentación de libjpeg sobre el JPEG progresivo más arriba, así que realiza mediciones con tus propias imágenes y tu formato de salida. La extracción de ThumbHash se factura como un cargo por metadatos; consulta la documentación del Robot para conocer las condiciones vigentes.
Fuentes
- libjpeg-turbo: documentación de la biblioteca libjpeg (compatibilidad con JPEG progresivo y modo de imagen con búfer)
- Especificación PNG del W3C, tercera edición (entrelazado y extracción de pasadas)
- MDN: guía de tipos y formatos de archivos de imagen
- Google: preguntas frecuentes sobre WebP (visualización progresiva o entrelazada)
- Especificación de AV1 Image File Format (AVIF) v1.2.0 (alcance y elementos de imagen en capas)
- libavif: manual de avifenc (opciones --progressive y --layered)
- Registro de cambios de libavif (encoding de AVIF en capas y renderizado progresivo en visores)
- React: renderToPipeableStream (transmisión continua, estructura básica y contenido alternativo de Suspense)
- nginx: ngx_http_proxy_module (proxy_buffering y X-Accel-Buffering)
- Next.js: guía de alojamiento propio (transmisión continua y almacenamiento en búfer del proxy)
- README del middleware compression de Express (res.flush y salida almacenada en búfer)
- Glosario de MDN: bloqueo del renderizado
- web.dev: optimiza Largest Contentful Paint (componentes de LCP)
- web.dev: optimiza Cumulative Layout Shift