The Async CSS Test Suite

Test suite created 2014-12-06 and updated on 2022-07-20 and 2022-11-15

I have constructed a few demo pages to illustrate which techniques do and don’t work for getting a stylesheet to load without blocking the rest of a page.

A typical, blocking link tag

First, the simple approach: simply placing a CSS <link> tag in the head. This is the method recommended by typography.com; it blocks later scripts from executing and completely blocks page render. In some cases, this is desirable, although for me, it is unacceptable for loading web fonts. This page will not appear to render for 5 seconds while it waits for the (server-delayed) stylesheet to load:

http://alanhogan.com/files/async-css/baseline-test.html

Non-blocking approaches

Here are two approaches that are satisfactory to me. JavaScript “waits” for the page to finish initial parse/execution and adds a tag to the head. Note that there would be flash of unstyled text (FOUT) and a re-render with the web font when loaded. This is desirable for me. These approaches use the same JavaScript code as each other, just placed in different parts of the HTML file; there seems to be no difference.

http://alanhogan.com/files/async-css/head-async-test.html

http://alanhogan.com/files/async-css/body-async-test.html

Update, 2022-04-29: I added onload-based detection to the "head-async-test" page and saved the result as:
http://alanhogan.com/files/async-css/head-async-test-with-js.html

Mixed-result approaches

These last two approaches are close but don’t cut it, as they still block render by adding the <link> tag to the head too soon.

http://alanhogan.com/files/async-css/head-async-test-no-timeout.html

http://alanhogan.com/files/async-css/body-async-test-no-timeout.html

Browsers were tested as noted in each test’s observed results section. Originally, that included Chrome, Firefox, Safari, and MSIE 6 – 11; newer tests drop most versions of MSIE because there’s no point. Tests below this paragraph were added in 2022 or after.

Now let’s try blocking the page with a dynamically inserted link tag

There are reasons you might want this.

http://alanhogan.com/files/async-css/head-try-blocking-1.html — mixed results

http://alanhogan.com/files/async-css/head-try-blocking-2.html - successful blocking

http://alanhogan.com/files/async-css/head-try-blocking-3.html - mixed results

What about a disabled link tag?

<link rel=stylesheet disabled /> tags define a stylesheet for inclusion, without applying it; the disabled property can be toggled at will with JavaScript.

http://alanhogan.com/files/async-css/disabled-link-1.html — non-blocking, but requested anyway by Chrome, Firefox, and MSIE (in which it is also blocking)

http://alanhogan.com/files/async-css/disabled-link-2.html — immediately re-enabled link tag becomes blocking only in Safari (and MSIE), non-blocking in Chrome and Firefox

by alan hogan