"Eliminate render-blocking CSS in above-the-fold content"
Asked Answered
U

7

156

I've been using Google PageSpeed insights to try and improve my site's performance, and so far it's proven extremely successful. Things like deferring scripts worked beautifully, since I already had an in-house version of jQuery's .ready() to defer scripts until the page had loaded fully, all I had to do was inline that particular function and move the full scripts to the end of the page. That worked great.

But now I find myself glaring at the one remaining yellow dot on the checklist: "Eliminate render-blocking CSS in above-the-fold content".

The way my CSS is set up is to have one global _.css file containing styles that apply to the page structure in general, or are used in more than one or two places across the site. Most pages then have an associated CSS file (for instance, party.php has party.css) containing styles specific to that particular page. All CSS files are cached indefinitely, as I append /t=FILEMTIME to filenames (and later remove them with .htaccess) in order to guarantee that files are updated when they are changed.

So anyway, Google recommends inlining critical styles needed for above-the-fold content. Trouble is... well, take a look at this screenshot: http://prntscr.com/1qt49e

As you can see... ALL of the content is above-the-fold! People hate scrolling, especially on a game that involves loading many pages. So I designed the site to fit on one screen (assuming a good enough resolution). So that means... ALL of the styles apply to above-the-fold content! So... is there any solution? Or am I stuck with that yellow mark on an otherwise near-perfect score?

Unseam answered 12/9, 2013 at 10:3 Comment(3)
its ironic that that above-the-fold content for the screenshot is taking long to load :) In fact, for me, the screenshot never got loaded eventuallyMarutani
@Marutani Probably got deleted. Prntscr isn't exactly meant for permanence, and I didn't expect this question to be quite so popular.Unseam
yes, all good, was just a light commentMarutani
S
187

A related question has been asked before: What is “above-the-fold content” in Google Pagespeed?

Firstly you have to notice that this is all about 'mobile pages'.
So when I interpreted your question and screenshot correctly, then this is not for your site!

On the contrary - doing some of the things advised by Google in their guidelines will things make worse than better for 'normal' websites.
And not everything that comes from Google is the "holy grail" just because it comes from Google. And they themselves are not a good role model if you have a look at their HTML markup.

The best advice I could give you is:

  • Set width and height on replaced elements in your CSS, so that the browser can layout the elements and doesn't have to wait for the replaced content!

Additionally why do you use different CSS files, rather than just one?
The additional request is worse than the small amount of data volume. And after the first request the CSS file is cached anyway.

The things one should always take care of are:

  • reduce the number of requests as much as possible
  • keep your overall page weight as low as possible

And don't puzzle your brain about how to get 100% of Google's PageSpeed Insights tool ...! ;-)

Addition 1: Here is the page on which Google shows us, what they recommend for Optimize CSS Delivery.

As said before, I don't think that this is neither realistic nor that it makes sense for a "normal" website! Because mainly when you have a responsive web design it is most certain that you use media queries and other layout styles. So if you are not gonna load your CSS first and in a blocking manner you'll get a FOUT (Flash Of Unstyled Text). I really do not believe that this is "better" than at least some more milliseconds to render the page!

Imho Google is starting a new "hype" (when I have a look at all the question about it here on Stackoverflow) ...!

Swedish answered 14/9, 2013 at 15:40 Comment(12)
Great answer. the trouble is that google seems to penalise you if you have a slower page. Hence they enforce you to adhere to their ideas be it great or utterly stupid. :(Mesentery
@Swedish not everthing that comes from Google is the "holy grail" LOL. I was scratching my head to achieve 100, but stopped at 92 after reading this comment.Issie
You should emphasize more, the fact, that Google doesn't adhere to their own suggestions.Thyself
@Issie That's what I have too and I don't actually know anyone with more than 92!Culosio
Additional requests will become less of a problem with HTTP/2 and SPDY, from Wikipedia, "Additional performance improvements in the first draft of HTTP/2 (which was a copy of SPDY) come from multiplexing of requests and responses to avoid the head-of-line blocking problem in HTTP 1 (even when HTTP pipelining is used), header compression, and prioritization of requests."Wimble
been trying to get my page up from 72 mobile and 80 desktop but had the same issue. I refuse to place my css somewhere lower and possibly degrade user experience by showing FOUT!Subscription
"And not everything that comes from Google is the "holy grail" just because it comes from Google. " Agreed. But try telling that to clueless managers and clients :)Terminus
@Alan Sutherland So, what you do when your css are cdn?Flame
Their recommendation makes sense in theory. But in my opinion good CSS is sometimes hard to split in "above and below the fold". It's just not how CSS works. Sure you can hack it like that, but if this is what it takes, I refuse to go for that perfect score. I feel they're making a mistake.Ries
I'm 100% with you! checking the page where google tells us to optimize will show this result: developers.google.com/speed/pagespeed/insights/… silly. :)Marsha
@MartinPfeffer silly to test a DevDocs page, you should at least test the B2C Google pages developers.google.com/speed/pagespeed/insights/… -- developers.google.com/speed/pagespeed/insights/…Meetinghouse
The points of this list should be considered as tips, the dev team should be smart enough to solve the most important points and leave the others.Meetinghouse
G
18

How I got a 99/100 on Google Page Speed (for mobile)

TLDR: Compress and embed your entire css script between your <style></style> tags.


I've been chasing down that elusive 100/100 score for about a week now. Like you, the last remaining item was was eliminating "render-blocking css for above the fold content."

Surely there is an easy solve?? Nope. I tried out Filament group's loadCSS solution. Too much .js for my liking.

What about async attributes for css (like js)? They don't exist.

I was ready to give up. Then it dawned on me. If linking the script was blocking the render, what if I instead embedded my entire css in the head instead. That way there was nothing to block.

It seemed absolutely WRONG to embed 1263 lines of CSS in my style tag. But I gave it a whirl. I compressed it (and prefixed it) first using:

postcss -u autoprefixer --autoprefixer.browsers 'last 2 versions' -u cssnano --cssnano.autoprefixer false *.css -d min/ See the NPM postcss package.

Now it was just one LONG line of space-less css. I plopped the css in <style>your;great-wall-of-china-long;css;here</style> tags on my home page. Then I re-analyzed with page speed insights.

I went from 90/100 to 99/100 on mobile!!!

This goes against everything in me (and probably you). But it SOLVED the problem. I'm just using it on my home page for now and including the compressed css programmatically via a PHP include.

YMMV (your mileage may vary) pending on the length of your css. Google may ding you for too much above the fold content. But don't assume; test!

Notes

  1. I'm only doing this on my home page for now so people get a FAST render on my most important page.

  2. Your css won't get cached. I'm not too worried though. The second they hit another page on my site, the .css will get cached (see Note 1).

Gallenz answered 21/8, 2016 at 18:30 Comment(6)
Thank you for your dedication and research, however I personally will not dream of doing that :DUnseam
So what's the point, except for trying to achieve a score which won't really help anything?Cathead
Neat that you got your score higher, but now each page on your site will have more weight. Still though, good find.Salim
@Salim Thanks! See my note 2 in the post. Once they hit a second page, the css gets cached, and the weight issue goes away.Gallenz
@Cathead The point of higher score? More money for me. The higher my website is in Google, the more likely someone is to click on it and become a customer. Because Google uses page speed to determine ranking, I decided to improve my score.Gallenz
@NiettheDarkAbsol :) Yes, I hear you. :| I didn't like doing it. But at the end of the day, a higher ranking [for me] means more $$. I was willing to bend my ideals of coding in this case, to meet that priority.Gallenz
F
9

Few tips that may help:

  • I came across this article in CSS optimization yesterday: CSS profiling for ... optimization
    A lot of useful info on CSS and what CSS causes the most performance drains.

  • I saw the following presentation on jQueryUK on "hidden secrets" in Googe Chrome (Canary) Dev Tools: DevTools Can do that. Check out the sections on Time to First Paint, repaints and costly CSS.

  • Also, if you are using a loader like requireJS you could have a look at one of the CSS loader plugins, called require-CSS, which uses CSSO - a optimzer that also does structural optimization, eg. merging blocks with identical properties. I used it a few times and it can save quite a lot of CSS from case to case.

Off the question: I second @Enzino in creating a sprite for all the small icons you are loading. The file sizes are so small it does not really warrant a server roundtrip for each icon. Also keep in mind the total number of concurrent http requests are browser can do. So requests for a larger number of small icons are "render-blocking" as well. Although an empty page compare to yours, I like how duckduckgo loads for example.

Fiesole answered 16/9, 2013 at 19:36 Comment(1)
Seems duckduckgo also doesn't care about their page score, check hereSwordsman
G
6

Please have a look on the following page https://varvy.com/pagespeed/render-blocking-css.html . This helped me to get rid of "Render Blocking CSS". I used the following code in order to remove "Render Blocking CSS". Now in google page speed insight I am not getting issue related with render blocking css.

<!-- loadCSS -->
<script src="https://cdn.rawgit.com/filamentgroup/loadCSS/6b637fe0/src/cssrelpreload.js"></script>
<script src="https://cdn.rawgit.com/filamentgroup/loadCSS/6b637fe0/src/loadCSS.js"></script>
<script src="https://cdn.rawgit.com/filamentgroup/loadCSS/6b637fe0/src/onloadCSS.js"></script>
<script>
      /*!
      loadCSS: load a CSS file asynchronously.
      */
      function loadCSS(href){
        var ss = window.document.createElement('link'),
            ref = window.document.getElementsByTagName('head')[0];

        ss.rel = 'stylesheet';
        ss.href = href;

        // temporarily, set media to something non-matching to ensure it'll
        // fetch without blocking render
        ss.media = 'only x';

        ref.parentNode.insertBefore(ss, ref);

        setTimeout( function(){
          // set media back to `all` so that the stylesheet applies once it loads
          ss.media = 'all';
        },0);
      }
      loadCSS('styles.css');
    </script>
    <noscript>
      <!-- Let's not assume anything -->
      <link rel="stylesheet" href="styles.css">
    </noscript>
Gladygladys answered 17/2, 2016 at 9:14 Comment(7)
When I use the mentioned function it reduces the pageSpeed score. The function I wrote is: jsfiddle.net/kvfzbxxo Can you help me out?Moot
I have implemented this same function on the following url and please have a look on the speed here "whitecashback.in" you can look at the source url and find the function "loadCSS" at the footer. This will help you to understand that how did I implemented the code. The page speed should increase as css is loading after the page.Gladygladys
I have used this code: jsfiddle.net/sbpa1hun .Now the CSS is not being loaded in the website.Moot
I mentioned that after adding this code: jsfiddle.net/sbpa1hun which is being used in your website, my website lost all styles. It creases page speed but the CSS is not working anymore! Can you help me some how? I am getting around 40 in page speed. But adding your code I get around 70. But could not get the CSS working.Moot
If you are trying to do this in jsfiddle then this will not work, please try this code in your website, jsfiddle will block loading css for external websites. Because you are loading css of external sources using javascript. So please try to do this in your website. Also try to include jquery files, they are missing in your script. After including js files, this may work. Also please note, https sites may work in jsfiddle. You are getting this error : "Blocked loading mixed active content". You need to resolve this first.Gladygladys
Thank you for writing a blog article on it. The combined_css is not loading for some reasons. Basically the appendAtLast os not functioning. And if I use loadCss for all three css files it reduces the pageSpeed from 44 to 39.Moot
@AmukSaxena, Can I use this to load https://cdnjs.cloudflare.com/ajax/libs/foundation/5.5.2/css/foundation.min.css, because google is asking me also to eliminate render blocking, specifically all my css file but all of them are cdn.Flame
A
4

I too have struggled with this new pagespeed metric.

Although I have found no practical way to get my score back up to %100 there are a few things I have found helpful.

Combining all css into one file helped a lot. All my sites are back up to %95 - %98.

The only other thing I could think of was to inline all the necessary css (which appears to be most of it - at least for my pages) on the first page to get the sweet high score. Although it may help your speed score this will probably make your page load slower though.

Anaclitic answered 18/9, 2013 at 18:38 Comment(1)
Smashing magazine has 100% score in pagespeed test developers.google.com/speed/pagespeed/insights/…Arsis
N
2

The 2019 optimal solution for this is HTTP/2 Server Push.

You do not need any hacky javascript solutions or inline styles. However, you do need a server that supports HTTP 2.0 (any modern server version will), which itself requires your server to run SSL. However, with Let's Encrypt there's no reason not to be using SSL anyway.

My site https://r.je/ has a 100/100 score for both mobile and desktop.

The reason for these errors is that the browser gets the HTML, then has to wait for the CSS to be downloaded before the page can be rendered. Using HTTP2 you can send both the HTML and the CSS at the same time.

You can use HTTP/2 push by setting the Link header.

Apache example (.htaccess):

Header add Link "</style.css>; as=style; rel=preload, </font.css>; as=style; rel=preload"

For NGINX you can add the header to your location tag in the server configuration:

location = / {
    add_header Link "</style.css>; as=style; rel=preload, </font.css>; as=style; rel=preload";
}

With this header set, the browser receives the HTML and CSS at the same time which stops the CSS from blocking rendering.

You will want to tweak it so that the CSS is only sent on the first request, but the Link header is the most complete and least hacky solution to "Eliminate Render Blocking Javascript and CSS"

For a detailed discussion, take a look at my post here: Eliminate Render Blocking CSS using HTTP/2 Push

Niobic answered 17/3, 2019 at 16:16 Comment(2)
I could be understanding wrong, but wouldn't Server Push cause the CSS to be sent every time you load the page, rather than just once before it's cached?Unseam
Yes, there are a few techniques such as cookies which can help avoid that. Take a look at the section on selectively pushing here: nginx.com/blog/nginx-1-13-9-http2-server-pushNiobic
W
0

Consider using a package to automatically generate inline styles from your css files. A good one is Grunt Critical or Critical css for Laravel.

Wrongheaded answered 6/4, 2017 at 13:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.