When a user requests a page, it can take from 200 to 500ms for the backend server to create the HTML. During that time the browser is idle, waiting for data to arrive. Developers can speed up start render times and the display of useful content by flushing the buffer. Flushing HTML sends a partial HTML response to the browser, which modern browsers can display. Flushing allows the browser to start fetching components and rendering the response while the backend can continue creating the rest of the HTML page.
Chunking for Speed
These partial responses are called chunks, from HTTP 1.1’s chunked encoding. Chunked encoding allows developers to send pieces of content to the browser, essentially breaking up a web page into separate components. This allows developers to progressively display portions of web pages, sending the most important parts to the client first.
Flushing in PHP
In PHP you can use the flush() function to flush HTML from the buffer. For example:
<html> <head> <title>Flush Example Page</title> <link rel="styles.css" href="my.css" /> <script src="script.js"></script> </head> <?php ob_flush(); ?> <?php flush(); ?> <body>...
Flushing right after the HEAD of your HTML document allows the browser to download the files in the head, and allows more downloads to happen in parallel. Yahoo! uses this technique to flush their page header containing a search box, using a flush right after their header div:
...</a></h2></div><div id="so" class="menu"><a id="so-link" class="menu-link" href="http://search.yahoo.com/preferences/preferences">Options<s></s></a><div id="so-menu" class="menu-bd"><ul><li><a href="http://search.yahoo.com/web/advanced?ei=UTF-8&p=response&fr=sfp">Advanced Search</a></li><li><a href="http://search.yahoo.com/preferences/preferences?pref_done=http%3A%2F%2Fsearch.yahoo.com%2Fsearch%3Fei%3DUTF-8%26p%3Dresponse%26fr%3Dsfp&.bcrumb=AEbU7zIj42B&tmpl=&fr=sfp">Preferences</a></li></ul> <hr><ul><li><a href="http://advertising.yahoo.com/">Advertising Programs</a></li><li><a href="http://help.yahoo.com/l/us/yahoo/search/basics/basics-23.html">About This Page</a></li></ul></div></div><input type="hidden" name="type_param" id="type_param" value=""><div id="at" class="sd sa-hidden"><h2 class="off-left">Search Direct</h2></div></div><div class="ursa-ft ft"></div></form></div></div></div> <?php flush(); ?> results content below here...
The Yahoo! Search results page looks like this after flushing this first search form chunk:
Waterfall of Yahoo! Search Flushing
The waterfall below shows the effect of flushing the buffer right after the page content header (see Figure 2). Note that two images load well before the HTML completes loading, pushing the start render time before the HTML load time.
Yahoo! Search Second Chunk
The Yahoo! Search results server next sends a second chunk of HTML with the search results (just sending the “above the fold” contents here would be ideal), see Figure 3.
Ideally you want to flush just enough initial useful content (say a header that loads quickly) to let the user see or interact with the web page, and leave any heavy database queries till later in the page. Both Yahoo Search and Google use this method of flushing to speed up start render times.
Further Reading
- Automatic Flushing with Rails
- Shows how to tweak Rails to flush.
- Flushing the Document Early
- Summary post by Steve Souders from his High Performance Websites book.
- PHP Documentation on Flush function
- Progressive Rendering via Multiple Flushes
- Stoyan Stefanov’s take on Flushing, includes tool used above to show chunked output.