I'm trying to eliminate 2 CSS files that are render blocking on my site - they appear on Google Page Speed Insights. I have followed different methods, none of which were a success. But, recently, I found a post about Thinking Async and when I applied this code: <script async src="https://third-party.com/resource.js"></script>it did eliminate the problem.

However, after publishing, the page lost the styling. I'm not too sure as to what is going on because the code works but it's the styling after upload that doesn't work. Would appreciate your help with this. Thanks

Are you applying async to styles or scripts? The style loads some time after you load the page or it never appears?
– kamusSep 24 '15 at 13:17

I applied the async attribute to styles and placed them in the header.
– PaulinaSep 24 '15 at 13:33

The thing with styles is that a re-rendering will be triggered if you load them late (e.g. in the body), and is not allowed in the standards (but since browsers are very forgiving it will work anyway). If the problem is slow response times from a third party server, perhaps you can simply host them on your server instead?
– Josef EngelfrostSep 24 '15 at 14:56

6 Answers
6

The trick to triggering an asynchronous stylesheet download is to use a <link> element and set an invalid value for the media attribute (I'm using media="none", but any value will do). When a media query evaluates to false, the browser will still download the stylesheet, but it won't wait for the content to be available before rendering the page.

<link rel="stylesheet" href="css.css" media="none">

Once the stylesheet has finished downloading the media attribute must be set to a valid value so the style rules will be applied to the document. The onload event is used to switch the media property to all:

This method of loading CSS will deliver useable content to visitors much quicker than the standard approach. Critical CSS can still be served with the usual blocking approach (or you can inline it for ultimate performance) and non-critical styles can be progressively downloaded and applied later in the parsing / rendering process.

This technique uses JavaScript, but you can cater for non-JavaScript browsers by wrapping the equivalent blocking <link> elements in a <noscript> element:

Ok.. I didn't know that you can reference element attributes in the on-handlers just by mentioning their name. I always thought 'event' is the only exception.
– TeemohMay 23 '17 at 4:21

So how do you keep your page from flashing as it rerenders everything? Plus do you inline core app shell styles so your page has some initial layout instead of rendering something Lynx would be proud of?
– Chris LoveJan 10 '18 at 18:38

2

Seems to still work for me. After doing this I know longer get a warning in PageSpeed Insights for this file.
– AndyWarrenMar 16 '18 at 19:13

2

this is working for me (08-july -2018) . And it giving good score in pagespeed insight
– abilash erJul 8 '18 at 7:28

Example 2 loads Javascript, but the question is about loading CSS. Do you know if example 2 works also for CSS, if you change from <script> to <style rel=stylesheet>? (Just curious. I'm going to use loadCSS (i.e. your example 3) instead, if I need to load CSS later.)
– KajMagnusSep 4 '17 at 14:36

The function below will create and add to the document all the stylesheets that you wish to load asynchronously. (But, thanks to the Event Listener, it will only do so after all the window's other resources have loaded.)

Are there any drawbacks of this method if we compare it say with the loadCSS approach? It seems, the classical code var newStyle = document.createElement("link"); newStyle.rel = "stylesheet"; newStyle.href = "stylesheet.css"; document.getElementsByTagName("head")[0].appendChild(newStyle); inside the <script> tag in the page body does its work excellently - even in old browsers like MSIE8.
– TecManApr 23 '18 at 13:22

@TecMan yes there are. As you can see, this function does it's job on window.load event. So, download starts when everything is downloaded. No luck there. You need non blocking loading as soon as possible to start.
– Miloš ĐakonovićNov 13 '18 at 13:17

I think the async attribute is ignored, as the script tag does not have a src to load asynchronously... or is it really useful here? Also can you elaborate a bit more on which value to use as a nonce?
– PhilippSep 5 '18 at 11:14