Don’t fight the browser preload scanner


Web Development


One overlooked aspect of optimizing page speed involves knowing a bit about browser internals. Browsers make certain optimizations to improve performance in ways that we as developers can’t—but only so long as we don’t thwart those optimizations unintentionally.

One internal browser optimization to understand is the browser preload scanner. In this post, we’ll talk a bit about how the preload scanner works—and more importantly, how you can avoid getting in its way.

What’s a preload scanner? #

Every browser has a primary HTML parser that tokenizes raw markup and processes it into an object model. This all merrily goes on until the parser pauses when it finds a blocking resource, such as a stylesheet loaded with a &LTlink> element, or script loaded with a &LTscript> element without an async or defer attribute.

HTML parser diagram.
Fig. 1: A diagram of how the browser’s primary HTML parser can be blocked. In this case, the parser runs into a &LTlink> element for an external CSS file, which blocks the browser from parsing the rest of the document—or even rendering any of it—until the CSS is downloaded and parsed.

In the case of CSS files, both parsing and rendering are blocked in order to prevent a flash of unstyled content (FOUC), which is when an unstyled version of a page can be seen briefly before styles are applied to it.

The home page in an unstyled state (left) and the styled state (right).
Fig. 2: A simulated example of FOUC. At left is the front page of without styles. At right is the same page with styles applied. The unstyled state can occur in a flash if the browser doesn’t block rendering while a stylesheet is being downloaded and processed.

The browser also blocks parsing and rendering of the page when it encounters &LTscript> elements without a defer or async attribute.

Leave a Reply

Your email address will not be published. Required fields are marked *