This article shows a technique that can be used to download style sheets asynchronously to prevent their downloads from blocking the rendering of the page so that visitors get the information content as quickly as possible.
Warning! This post is all well-intentioned, but it is not responsible for the person who reads it to be aware of the problems that will be encountered. The community quickly gave me a lot of feedback (some feedback I was grateful for), and it became increasingly apparent that the technology was not as stable as I had hoped. Unlike my success in testing and exploiting it, many developers have encountered problems with IE and Firefox (F-F beta crashes) while others report success in Chrome and Safari. My advice now is: do not use it for products. I plan to take care of the feedback and update this article with any relevant information.
The principles behind these techniques are not new. For example, the filament (filament) technology group has released a lot of content about loading CSS and fonts. I write this article to record my thoughts and views on loading non-blocking resources.
The trick to triggering asynchronous style downloads is to use an element and set an unavailable value for the media property (I'm using media= "none", but any other value is OK). When the result value of a media query is calculated to be false, the browser still downloads the style sheet, but does not wait for the resource of the stylesheet to be available before rendering the page.
- <link rel="stylesheet" href="css.css" media="None">
When the style sheet is loaded, the media property must be set to an available value so that the style rule can be applied to the HTML document the OnLoad event can be used to switch media properties to all:
CSS Code copy content to clipboard
- <link rel="stylesheet" href=" css.css" media= "none" onload="if (media!= ' all ') media = ' All '>
This method of loading CSS will be much faster than the standard method of sending useful information to visitors. Critical CSS loading can still be handled in a general blocking manner (or you can inline it for final performance), while unimportant styles can be downloaded slowly and applied at a later point in the parsing/rendering process.
This technique uses JavaScript, but you can also use a <NOSCRIPT>
The technology has a side effect. When a non-blocking style sheet finishes loading, the document is redrawn to reflect any new style rules it defines. The injection of new styles into the page triggers the return of the content, but this is only a problem when the page is loaded for the first time without a history cache. Because of any performance-related things, you will have to make the necessary adjustments when you need to control the return consumption over the potential speed advantage.
Load fonts with non-blocking CSS
The performance of the first drawing of the font is a problem, they are blocked resources, and the text to which they are applied is not visible when the font is downloaded. Using the non-blocking link in the example above, it is possible to download the style sheet containing the font data behind the scenes without blocking the embossed rendering:
CSS code copy content to clipboard
- <link rel= "stylesheet" href="Main.css">
- <link rel="stylesheet" href=" font.css" media= "none" onload="if (media!= ' all ') Media=' All ' >
FONT.CSS contains a base64 encoded Woff version of the Merriweather font.
CSS code copy content to clipboard
@font-face {
Font-family:merriweather;
Font-style:normal;
font-weight:400;
Src:local (' Merriweather '), url (' data:application/x-font-woff;charset=utf-8;base64,... ')
}
MAIN.CSS contains all the style rules that need to be applied to a site. The following is the font declaration:
CSS code copy content to clipboard
Body {
Font-family:merriweather, "Lucida Grande", ...;
}
When the font is being downloaded, the first matching fallback font (here is Lucida Grande) is used to render the contents of the page. Once the font style sheet is applied, the Merriweather is used. I try to make sure that the fallback fonts share similar layout features with the preferred font, so the inevitable reflow is as subtle as possible.
I used my Google Analytics Debugger site to compare tests with blocking and non-blocking in Chrome, based on a simulated 3G network connection. The local test produced the network diagram shown below; Note that the domcontentloaded was triggered at an earlier 450ms, and resources are faster to download after using non-blocking technology:
Simulate graphics for a 3G network. Blocked fonts are displayed at the top. A non-blocking font is displayed at the bottom.
Deploying it to a test server and running the Webpagetest construct in a 3G-connected environment produces the following timeline:
3G time line. A blocked font appears at the top, and a non-blocking font is displayed at the bottom.
Both methods took 2.8 seconds to complete the rendering of the page, but the Non-blocking method made the drawing 1 seconds earlier than the usual blocking method. Running the same test while the main style sheet is inline shows the time advantage of having non-blocking CSS applied to processing fonts for 0.7 seconds:
3G timeline for main CSS content. Blocked fonts are displayed at the top, and non-blocking fonts are displayed at the bottom.
This technique is really good for fonts, but I also recommend keeping a close eye on the new CSS font loading module, which gives us more control over font loading.
Summarize
Loading fonts is an example of applying non-blocking technology, and he can also be used for other purposes, such as separating JavaScript-enhanced styles from the core CSS.
I've started to try to divide the style into a framework (the core layout) and the idea of presenting (everything else), which can block page rendering for important page layouts, while the visible style data is delayed for a while.