Progressive Output Flushing

The update notes for Perch 2.7.10 included a mysterious entry about progressive output flushing and improved performance. Page load speed is something we care a lot about, and this is another way Perch helps to keep your sites feeling fast. So what is it?

Whilst a good 80% of your site performance tuning happens at the front end once the page has been delivered to the browser, none of that helps much if the page takes too long to arrive from the server. That part – the time it takes to actually build the HTML page – is the responsibility of your CMS, and every aspect of Perch is designed to make it as quick as possible.

The browser can’t start displaying the page until it has received the HTML from the server. Crucially, it also can’t begin to request resources like stylesheets, scripts, fonts and images until it knows what the page needs. These resources are often a point of slowness, so the sooner they can be requested, the better. In performance terms, this is often call the Time To First Byte (TTFB), and even though it’s not always the best thing to objectively measure, we still want to get the browser working on that HTML as soon as we possibly can.

Getting chunky

HTTP 1.1 (the protocol used by browsers and servers to talk to each other) has a featured called chunked transfer encoding which enables a server to send the response in chunks rather than all at once. For a web page, that means that parts of the HTML can be sent to the browser before the rest of the page is ready. If a browser can start working on the <head> section before it has the <body> it can at least start to request stylesheets, web fonts and so on nice and early.

The overall time it takes the server to build and send the HTML of the page stays the same, but the browser can start work on those resources earlier, so the total page rendering time is reduced.

Flush early and often

Unlike many other templated systems, Perch doesn’t need your entire page to finish building before it can start sending parts of the page back to the browser. Perch builds a page top-to-bottom, pulling in layouts and templates when needed as it goes. This avoids the trap that many other systems fall into of assembling content then trying to inject it into a master HTML layout – an approach that prevents any meaningful progressive flushing of output to the browser.

From Perch and Perch Runway 2.7.10, we now progressively flush output to the browser at the following points:

  1. When a page section is output with layouts
  2. When a region of content is output with perch_content() or perch_content_custom()
  3. When navigation or breadcrumbs are displayed
  4. When a template is output with perch_template()

We’ll also be adding it to obvious first-party add-ons like Blog as and when they get updated.

Take the common example where the top portion of your pages are managed using a layout. As soon as that layout is done, Perch flushes the output to the browser. The browser can then set to work on the page while Perch moves on to templating up the page body. Got a big news listing next? As soon as it’s done it gets flushed and sent. Sidebar in a layout? Built and sent. Footer? The same.

This method of build-and-send means that the server is never sitting on finished work that the browser could be making use of. The net result is faster pages and happier site visitors.

This all happens by default – you don’t have to turn it on or do anything differently. Just update to Perch or Runway 2.7.10 or newer.

But this is terrible for me!

I know some of you do weird things. You wrap Perch up in MVC frameworks, you pipe it to Rails and Node, you’re doing all sorts of craziness that could potentially not be expecting a chunked response. Progressive flushing is enabled by default, but you can just turn it off:

define('PERCH_PROGRESSIVE_FLUSH', false);

When that config flag is set, Perch reverts to the old behaviour of letting the web server flush its response whenever it sees fit – usually at the end of the page.

You may also read outdated comments on the web about it not working with gzip and whatnot, but that’s not the case anymore. This should all just work unless you’re doing something crazy like above.

Tell me more!

You can read more about this technique in Flushing the Document Early on Steve Souders’ site. Steve has written a couple of great books on performance that you might enjoy if you’ve read this far and are still vaguely interested.