What is Progressive Rendering?

Progressive rendering presents usable portions or increasingly complete versions of content as data becomes available. It avoids withholding the entire result until every resource or processing stage has finished.

How Progressive Rendering works

Progressive rendering is a strategy that spans encoding, transport, parsing, and presentation; it is not a single media format. At the file level, a progressive JPEG stores the image as a series of scans of increasing quality, so a decoder can show a coarse version of the whole picture from the first scan and refine it as more arrive, and an interlaced PNG transmits its pixels in seven passes. At the document level, a server can stream HTML so that the browser shows the page’s outer structure and placeholders while slower sections are still being produced; React’s streaming server renderer, for example, sends the fallback of a <Suspense> boundary first and the real content later. The two levels address different waits: web.dev’s breakdown of Largest Contentful Paint counts the time to the first byte of the HTML document and the time to load the image resource itself as separate subparts, so sending the document sooner does not shorten the download of an image it references, though the browser can start that download sooner when the HTML that arrives early already contains the image’s URL. In both cases the early output helps only if it actually reaches the screen early; reserving space for the final output keeps the replacement from moving the surrounding layout.

Key facts

  1. Which image formats can render progressively? JPEG when it is encoded in progressive mode, PNG and GIF when they are interlaced, and JPEG XL, though MDN notes that Safari renders JPEG XL only after the complete download. WebP cannot refine a whole-image preview: Google’s WebP FAQ says it offers no progressive or interlaced refresh in the JPEG or PNG sense, only incremental decoding that displays rows as their bytes arrive. AVIF depends on the encoding and the viewer. The AVIF specification supports progressive decoding through layered images but leaves the renderer free to show only the highest layer; libavif’s avifenc produces such a file with --progressive, and the libavif changelog names Chrome as a viewer that renders the layers progressively. MDN’s format guide, by contrast, states that AVIF does not support progressive rendering and that files must be fully downloaded before display, adding that the smaller size of AVIF files often makes up for this except for larger files. Converting to WebP or AVIF therefore does not by itself preserve the coarse-first effect: for AVIF, check the encoder setting and the target browsers; otherwise a separate placeholder has to provide it.
  2. What does a progressive JPEG cost? Mostly decoding work, not file size. The libjpeg documentation says progressive files are often slightly smaller than sequential files of the same quality and that the final image is identical. It also says each displayed scan takes about as much work to decode as a full image of the same size, and that intermediate scans are shown only if the application uses the library’s buffered-image mode; otherwise the decoder reads every scan and returns just the final image. Whether viewers see the refinement therefore depends on the decoder in use, not only on the file.
  3. Why does a streamed page still appear all at once? Usually something between the renderer and the browser is holding the bytes. nginx buffers proxied responses by default and passes data through as it is received only when proxy_buffering is off or the upstream sends X-Accel-Buffering: no, a header that nginx can be told to ignore with proxy_ignore_headers; the Next.js self-hosting guide adds that some cloud load balancers buffer responses by default and that reverse proxies between the load balancer and the application must also pass chunked responses through without buffering. Compression buffers a window of output to compress well; the Express compression README describes this for server-sent events and provides res.flush() to force the partially compressed response to the client. The application can cancel the effect itself: React documents that starting the stream in onAllReady instead of onShellReady gives no progressive loading. Once bytes do arrive early, CSS or JavaScript loaded up front can still block rendering.
  4. Does progressive loading cause layout shift? It can when the space for late content is not reserved. Google’s guidance on Cumulative Layout Shift lists images without dimensions and dynamically injected content among the most common causes of a poor score, and says to always set width and height on images and video or to reserve the space with CSS aspect-ratio. An image that refines inside a box of known size moves nothing around it; a replacement whose size differs from its placeholder can move the surrounding content unless a container already reserves the space.

When Progressive Rendering matters

Design for progressive rendering when meaningful page or media content can be prioritized ahead of secondary details. Unstable dimensions or poorly ordered updates can instead cause layout shifts and distracting visual changes.

How Transloadit helps with Progressive Rendering

Transloadit’s /image/resize Robot has a progressive parameter that interlaces the output so that browsers can show a low-resolution version of the whole image first; it is off by default. For formats where that does not apply, a Step that produces an image can extract a BlurHash or ThumbHash through output_meta, a compact placeholder to display while the full image loads. Image results in the Assembly Status also carry width, height, and aspect_ratio in their metadata, which is what a page needs to reserve the image’s box before it arrives.

The Robot documentation states a file-size increase for progressive without naming the output formats it applies to, which differs from what the libjpeg documentation says about progressive JPEG above, so measure with your own images and output format. ThumbHash extraction is billed as a metadata charge; see the Robot documentation for the current terms.

Explore Transloadit’s delivery capabilities

Sources

Turn media knowledge into a working pipeline

Connect uploads, processing, AI, storage, and delivery through one declarative API — with the encoding stack, scaling, and format churn handled for you.

Try Transloadit for free