Optimising CSS delivery according to Google - css

So I was running my site through Google's PageSpeed Insights and it told me that I could improve CSS delivery by delaying loading non-critical resources. In particular it referenced to the inclusion of font awesome:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
I figured I could delay its load by simply putting it before the scripts before the closing body tag, like so:
...
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="js/min/scripts.min.js"></script>
</body>
</html>
However! When taking a look at Google's documentation on delivery speed, I found two different solutions.
In my native language (Dutch; you can change the language of the documtnation in the right lower corner) the documentation states that I should place non-essential css below the closing html tag. This seems awefully odd to me. Wouldn't this complicate things when trying to access the file through JS? Why wouldn't you place it before the closing body tag?
...
</body>
</html>
<link rel="stylesheet" href="small.css">
However, in the English documentation things get more complicated and require JavaScript:
...
<script>
var cb = function() {
var l = document.createElement('link'); l.rel = 'stylesheet';
l.href = 'small.css';
var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h);
};
var raf = requestAnimationFrame || mozRequestAnimationFrame ||
webkitRequestAnimationFrame || msRequestAnimationFrame;
if (raf) raf(cb);
else window.addEventListener('load', cb);
</script>
</body>
</html>
Why would JS required? Isn't that a bit over the top?
What is wrong with my approach? Why can't you load non-critical CSS before the closing body tag?

An external stylesheet will block rendering of the page until it has been fully loaded. Google is recommending to place the style that is needed for the initially visible (critical, above the fold) part of the document inside <style> tags in the head (the only place where you can define non-inline style) to avoid this render-blocking. The non-critical style (what you don't directly see when you land on the page) is added as an external stylesheet inside the head after the HTML has been read. This way it's rendered first and only then will all other styles be loaded. All for the sake of showing the visitor the content as quickly as possible and not letting her/him wait any longer than necessary.
It think for most cases it is over the top what Google is recommending and they're just being freaky about a few milliseconds - their approach only makes sense somewhat if the CSS is huge. But I think it's hard, if not near impossible, to maintain with the current tools available. What for example if it is a returning visitor that has scrolled down the page at an earlier point and will automatically land there again (Opera is a browser that is very stubborn with this)? For that alone you'd need more JS and possibly juggle with the styles. That can't be a good way to go. And even for the initial display you'd have to stuff some media queries inside the head directly in order to try and get things right without resorting to full screen sections. That's all quite counterproductive and overcomplicating.
Putting <style> or <link> tags outside the head section might work but it's incorrect. I'm sure Google's not on that standpoint anymore and that the English version is the only valid documentation.
Edit - see comments for a nuance on this.
Even if one does do it the google way and get a 'good' score on PageSpeed Insights that doesn't mean too much. You could still hide the whole page and only show it when everything has been loaded (which isn't unusual) without that effecting the score.
I've personally decided to ignore it until they've implemented a feature where you can load CSS asynchronously (like you can with JavaScript and async already) like is announced in the documentation. It would still require a special use case then but at least you could build a framework for it. Not a fan of plugins for something rather trivial myself.
One important thing is missing in the Google documentation - providing a fallback when JavaScript has been disabled. Luckily with HTML5, <noscript> tags can be used for this :
<head>
/* other stuff */
<noscript><link rel="stylesheet" href="small.css"></noscript>
</head>
Sidenote - Google's own analytics script will prevent a perfect PageSpeed score because of the (logically) quick cache expiration they've set on it. Figure that.

I'd suggest you have a look at this repository: https://github.com/filamentgroup/loadCSS
LoadCSS is a very savvy script by the people at Filament Group to lazyload stylesheets in a way, that most browsers play along nicely.
If Javascript is disabled or for whatever reason the script won't work, there are fallbacks included as well.

To answer your specific questions:
Javascript is NOT required to accomplish what you want. There are several methods for loading CSS in a non-blocking fashion. Some rely on JS, some do not. Filamant Group's LoadCSS is a JS option. Critical Path's CSS Generator is one non-JS method. The process of generating the critical CSS can also be automated using Gulp or Grunt.
While your method will work it's not recommended. Google recommends loading the non-critical CSS files using Javascript so the CSS is loaded into the head after the page has finished loading.
Alternatives
There are 2 ways to improve your current implementation.
It sounds like you're currently loading 2 CSS files - your site's CSS, and font-awesome.min.css. This requires 2 HTTP requests and will cause a small delay. Combine the CSS from the 2 files into a single CSS file.
As the others have pointed out Google recommends inlining the critical CSS into the head of the page, and loading the remaining CSS in a non-blocking way. An alternative option I've found useful is to load the entire contents of the CSS into the head of the site within a style tag. I recommend this only if your CSS file is relatively small and minimized.
<head>
<style>
// ALL YOUR CSS
</style>
</head>

I think you are focusing on the wrong part of their (confusing) documentation. I think what they really are trying to share, is that you should put your critical CSS inlined into your html. Look at the blue class in the style tag
<html>
<head>
<style>
<!-- This is what they are trying to show -->
.blue{color:blue;}
</style>
</head>
<body>
<div class="blue">
Hello, world!
</div>
<script>
var cb = function() {
var l = document.createElement('link'); l.rel = 'stylesheet';
l.href = 'small.css';
var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h);
};
var raf = requestAnimationFrame || mozRequestAnimationFrame ||
webkitRequestAnimationFrame || msRequestAnimationFrame;
if (raf) raf(cb);
else window.addEventListener('load', cb);
</script>
</body>
</html>
I read the same documentation in french, which seems to be as outdated as your dutch version and here again, they placed the blue class inlined
<html>
<head>
<style>
.blue{color:blue;}
</style>
</head>
<body>
<div class="blue">
Hello, world!
</div>
</body>
</html>
<link rel="stylesheet" href="small.css">
What they are trying to tell, is that critical CSS can be put directly in html without loading the whole CSS file. In their example, the blue class is critical since it is the only one used.
Concerning the outside of the html tag, It is indeed invalid HTML, but browsers seems to allow it anyway. For the JS code part I guess they are trying to add the stylesheet in the header, but only when the JS will be executed, which mean at the end of the page load. At this point, you might want to think about code readability over performance.

Well, there are 3 main sections, where You can place
first is body, second is head and third is everywhere in html, try to work with it

Related

Elimiate CSS render-blocking, best way

i want to eliminate the render blocking from my website, but i can't.
I don't use external css files, or fonts, only just a big css file.
When i copyall content from css file in head AllcontentCSS, render blocking disappear from Google Page Insights
Is there a way to eliminate render blocking and include the css file with link in head instead to copy all css in style tag or is good to insert the css in body tag?
You are most likely looking for:
<link rel="stylesheet" href="yourFile.css" media="none" onload="if(media!='all')media='all'">
But, before you proceed, please read the following resources detailing the technique and its limitations:
initial article by Keith Clark
follow up by Taylor Hunt.
Make sure you also go through the links provided by Taylor Hunt. You probably want to use loadCSS function/polyfill from Filament Group.
But be aware this technique will cause FOUC on your page. You should divide your CSS into two parts:
layout basics (load normally - render blocking),
async styles (load async).

When and how do browsers render <style> tag in <body>?

I noticed that if I place <style> inside <body> the css would be applied to all elements after and before <style> tag.
So it looks to me that the css is processed when the page is loaded, similar behavior to javascript document ready event. Am I right? And if that is the case in which order would multiple <style> tags be processed?
TL;DR:
In short, the answer to your question is: once a <style> tag is met inside <body> everything stops and the CSSOM is being rebuilt and re-applied to all existing rendered (painted) content.
Placing <style> tags inside <body> is considered bad practice because it can create FOUC. But if your <style> tag only contains rules for elements placed after it in DOM, placing it in body is perfectly fine, as no FOUC can happen.
The render process of a page is quite complex. But, overly-simplified, here's what happens
<head> is read and CSSOM is built. All CSS is render blocking, unless explicitly specified otherwise by use of #media queries. The non-blocking CSS is still loaded, it's not entirely skipped.
DOM building and CSSOM building are ran in paralel, but all <script> execution is deferred until CSSOM has been built (on </head> tag met), at which point all loaded <script>s are ran, blocking DOM building. JS can make changes to CSSOM at this point. *
Placing <style> tags inside <body> interrupts everything (JS execution and DOM building), CSSOM is being updated and applied to the already rendered content, if any. Everything is resumed after.
* On further testing it appears <head> parsing is single threaded. CSSOM building does block javascript execution but it's done is stages, as each <link /> and <style> tags are met (a <script> placed after a <link> will only execute after the <link /> was resolved and applied to CSSOM). <script> tags placed in between CSS resources are not deferred until all CSS resources in <head> are parsed, as I initially thought.
And, of course js can make changes to CSSOM at run time. See this question I asked for more on how js execution is blocked by CSSOM building.
All the above apply to the normal loading, without considering async, which adds a whole new layer of complexity to it.
If you're interested in more details, I recommend going through the Performance chapter of Web Fundamentals, provided by Google.
Scope of CSS
A style element applies to the whole document, regardless of its position. It is applied as soon as it's loaded.
Reason for putting style tags in <body>
Since every browser has a limited number of threads for downloading a page's files (like JS, CSS, images and asynchronously loaded HTML, JSON or XML), people tend to include CSS files at the end of the body element instead of the classic approach of including them in the head element. This way the rest of the page can be loaded and rendered, and the styling is applied last. You would go this way if your CSS is purely for the looks (i.e. no required element hiding) in order to improve the user experience.
CSS files vs style rules in HTML
Including an external CSS file or putting the same rules in a style element have equivalent results regarding layout and styling. The external file has the downside of a little HTTP overhead, but the benefit of being cached for any further request. If your site consists of more than one page, you usually want to have one or more CSS files that are downloaded only once and re-used for most pages. In addition you can have page-specific rules in another file or within the HTML page.
So it looks to me that the css is processed when the page is loaded, similar behavior to javascript document ready event. Am I right?
No. The stylesheet is modified with the new CSS code when that code is added to the DOM. There's no delay until the rest of the DOM has finished loading. If there was you'd see a FOUC.
which order would multiple <style> tags be processed?
The order they appear in. Then the normal rules of the cascade apply.

Suggestions on why site is slow/how to speed up?

I know the website is very image based, I have limited plugins as much as I can and compressed CSS and styling. It shouldn't be as slow as it is. Any reason why this or what I can do to speed it up? Thanks
in my opinion
1- you are using too much css and javascript
2- Eliminate render-blocking JavaScript and CSS in above-the-fold content
3- you should optimize your image
4- you can upgrade your server to faster server
5- Enable compression and browser caching
and .....
EDIT:
how improve above steps:
1- for better performance its better to keep page size under 600kbit usually it's because of theme or the plugin we use, then if you can, change your template to an optimize version and reduce your unnecessary plugins. on the other hand there are some features that can handle by just few codes, but we rather to install a new plugin so new plugins has its self javascript and css
2-put all your javascript codes on the footer befoter </body> (help), and create a javascript loader for your css, that insert your css on the head.(help) simple example of render-blocking
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
<!-- do not insert css or javascript here -->
</head>
<body>
<!--
#################
contents
#################
-->
<script type="text/javascript" src="/dis/cssloader.js"></script>
<script type="text/javascript" src="/dis/scripts.js"></script>
</body>
</html>
and your cssloader
//cssloader.js
var version = "?v1";
var cb = function() {
var styles = [
"/dist/custom1.min.css",
"/dist/custom1.min.css",
];
var h = document.getElementsByTagName('head')[0];
for (var i = 0; i < styles.length; i++) {
var l = document.createElement('link');
l.rel = 'stylesheet';
l.href = styles[i]+version;
h.appendChild(l);
}
};
var raf = requestAnimationFrame || mozRequestAnimationFrame || webkitRequestAnimationFrame || msRequestAnimationFrame;
if (raf) raf(cb);
else window.addEventListener('load', cb);
3- optimizing image means to reduce your image scale as you can, and saved your images for web (if your are using photoshop it has an option to do this, it's obvious that it reduce your images quality )
4-sometime just some configuration on server , improve it's performance
5- if your are using apache, you should add some line of codes on your apache config so that comperssion and caching enable for it, you can do this by .htaccess too (help)(help)
This suffers from a grotesque amount of Javascript and CSS. Minifying them into a single file each or at least consistently using their minified versions will help, but at 7.1MB for a single page, including a 1.1MB image, you might consider that you're doing something fundamentally wrong regarding page design and use of images. Even on a fast desktop this is slow, and even with minified styles and scripts (and resized, not just 'optimized', images), on mobile it'll (still) be unusable.
Edit: That size is with ghostery enabled, so it's likely a bit on the low side, and those won't do anything to help your load time.

How to correctly load a stylesheet within the body?

I know I can just put the <link> tag in the body and apparently it works, but I know it's not "valid" html and I want to avoid issues with strict browsers like firefox, which ignore every behavior a web designer expects if it's not defined in the official specification.
So is there some official way to load a stylesheet in the body area of the html?
You can add your css in the head dynamically as well like below:
jsCode:
var head = document.getElementsByTagName("head")[0],
cssLink = document.createElement("link");
cssLink.href = "path/to/filenam.css";
cssLink.id="dynamic-css";
cssLink.media="screen";
cssLink.type="text/css";
head.appendChild(cssLink);
document.head.appendChild( linkElement );
…where linkElement is your style link. Nobody's forcing you to add stuff to the body, just add it to the head.
It is valid to link to a stylesheet in the body
The stylesheet keyword may be used with link elements. This keyword creates an external resource link that contributes to the styling processing model. This keyword is body-ok.
https://html.spec.whatwg.org/multipage/semantics.html#body-ok
https://html.spec.whatwg.org/multipage/links.html#link-type-stylesheet
Actually in older versions of HTML it was illegal to put a link element in the body element and must be only in the head section of the HTML document. From this link, there is a section that states this
it may only appear in the HEAD section of a document
So, just simply load the stylesheet into the head element, there is no possible reason for you, or for anyone to write illegal documents that do not satisfy the rules of W3.org.
<head>
<link rel="stylesheet" href="~/css/file.css" />
</head>
However, there is another question that you might be interested in reading, and in which condition you can add link element to the body section. Read the answer here.

What Exactly Happens When Some CSS Code Found on the Footer

I understand that CSS is used to decide about Layout and other styling things on Web Page. and If CSS is at the bottom of the page then everything (html elements, text, image, etc) will be displayed by using Browser's own styling and when browser find our CSS then it redesign pages again for us. It may be called repainting!
So, I understand that it will look very ugly repainting the page and user seeing it (FOUT - Flash of Unstyled Text - as expert named). But still, I want to understand about:
How much time this repainting can take? Approx value! I understand this can depend on content on the page.
What else happen or can happen?
My main concern right now is about using font-awesome CSS file (externally hosted on their own cdn which download css and font files). I want to know what will happen across devices if I place this at bottom of the page or delay its loading ? Currently it is placed on <head> section as
link rel='stylesheet' href='http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css' type='text/css' media='screen'
Use Del so that it should not look main part of the question. Main part of the question is about Some CSS at the bottom then What will happen to repaint, Blocking, etc. with measurement given or supported by measurement etc.
In the above case or in case when only part of document will get affected by CSS at the bottom then what will happen? Browser repaint everything, and what else? How much time it can take. Suppose, font-awesome is used at 10 icons placed in <i>.
I am never sure of what actually happens when CSS is at the bottom. So, please if you have any video or image showing flow then please mention here.
Base everything on performance across devices, and off course user experience as well. Thank you.
Update: I got something more for myself and for everyone.
Here is a function (delayLoadCss) Google suggest for css for below-the-fold content. Though, I am not going to go that extreme but what about doing that for Font-Awesome kind of CSS?
In my experience the loading of css will be virtually instantaneous no mater where it appear on the page--except in one instance: what will cause a delay in the browser applying your css is placing your css after a script element that takes time to complete.
This is why it is considered best practice to end your body section with your scripts, that way your page is rendered and styled before the browser commits to crunching through your scripts.
So if you html looks like this:
<head>
<link rel="stylesheet" type="text/css" href="/css/styles.css">
<script>
[long loading js]
</script>
</head>
<body>
... content
<script>
[long loading js]
</script>
</body>
Then your css will still be applied right off.
However if you structure it like this:
<head>
<script>
[long loading js]
</script>
<style>
[css here]
</style>
</head>
<body>
... content
<script>
[long loading js]
</script>
</body>
or even
<head>
<script>
[long loading js]
</script>
</head>
<body>
... content
<script>
[long loading js]
</script>
<style>
[css here]
</style>
</body>
Then your css will not be applied to the document until after the js has completed.
The first is best practice and I recomend keeping style tags out of your document completely, but certainly out of the body of your document. External style sheets placed above you script tags is the way to go... This is true for font awesome's externally hosted css also. The browser should not hang on rendering that unless your link to it appears after a script element that is taking up the browsers attention.
* EDIT *
However this post directly contradicts what I just said.
There are two cascades that occur with CSS.
The small Cascade: this is the parsing of an individual style sheet
The Big Cascade: This is where the browser performs three "small cascades", in this order:
User Agent (the web browser's native stylesheet)
Author (the stylesheet that you write)
User (the stylesheet the end user can write).
Your question is about what would happen if you put styles anywhere but the head. Let's discuss:
The browser has its own native stylesheet sitting in the background
The browser loads your HTML document first
The browser then reads the <head>
the browser loads assets in the <head>
the browser parses the rest of the document, i.e. the <body>. assets and style rules located here will be processed last.
the last <style> block, or the last stylesheet in your document is the one whose styles over ride everything else.
In a nutshell, the browser applies styles in the order in which they are seen. A stylesheet at the footer would make things worse, not better. I can't offer a quantifiable measurement of worse because I don't have your stylesheets or website.
All Browsers have FOUC (or FOUT). The duration of it is based on the speed of the browser and the quality of your stylesheet. A minified stylesheet which applies text styles immediately after the reset, and before other styles, usually has the least amount of FOUC.
The styles in the footer are not blocked from being processed, and they will not block styles in the <head>, either. Styles in the footer are simply processed last.
I appreciate the answer from Jeremythuff, however I would also like to answer as well and hope it helps you.
Approx it will take a time to download CSS file (if not cached and not inlined) + a moment. This moment depends on CPU, GPU, HD speeds (if cached) and content + scripts as you have already mentioned. In real practice you do not want to use [link href="..."/] at the end of body because of download time.
You also do not want to use inline styles, because they are not cached and this is yet another piece of code users will download with html, however, this solution can work with small inline styles. In practice it does not produce blinks.
I recommend the following schema:
HEAD > MAIN CSS > BODY > HTML > ADDITIONAL CSS > SCRIPTS
If scripts change default behavior of elements (for example preventing a link from clicking) I recommend to put scripts in head instead.
Now about fonts. In my opinion using external fonts is a bad practice. But if you want, fonts better to include in head because you probably cannot inline them in style tag. So the download time problem occurs here.
10 icons is nothing for nowadays CPUs even on mobile phones.
My advices are straightforward:
(if across devices, I also think of page weight because of slow mobile networks)
Have large additional css (significant difference between the size of html with and without css) - do not include at the end nor as [style]...[/style] (never caches), neither as [link href="..."] (takes download time).
Have small additional css - try with [style]...[/style] at the end of the body before scripts.
Do not worry about 10 icons rendering, worry about download time for 1st visiting users (for fonts).
Your questions are interesting... But there's a problem:
CSS stylesheets must be placed in the <head>!! (except if they are scooped)
Otherwise, your html markup is invalid. Then, every browser could handle it differently.

Resources