CSS delivery optimization: How to defer css loading?
Solution 1
If you don't mind using jQuery, here is a simple code snippet to help you out. (Otherwise comment and I'll write a pure-js example
function loadStyleSheet(src) {
if (document.createStyleSheet){
document.createStyleSheet(src);
}
else {
$("head").append($("<link rel='stylesheet' href='"+src+" />"));
}
};
Just call this in your $(document).ready()
or window.onload
function and you're good to go.
For #2, why don't you try it out? Disable Javascript in your browser and see!
By the way, it's amazing how far a simple google search can get you; for the query "post load css"
, this was the fourth hit...
http://www.vidalquevedo.com/how-to-load-css-stylesheets-dynamically-with-jquery
Solution 2
A little modification to the function provided by Fred to make it more efficient and free of jQuery. I am using this function in production for my websites
// to defer the loading of stylesheets
// just add it right before the </body> tag
// and before any javaScript file inclusion (for performance)
function loadStyleSheet(src){
if (document.createStyleSheet) document.createStyleSheet(src);
else {
var stylesheet = document.createElement('link');
stylesheet.href = src;
stylesheet.rel = 'stylesheet';
stylesheet.type = 'text/css';
document.getElementsByTagName('head')[0].appendChild(stylesheet);
}
}
Solution 3
This is how you do it using the new way:
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>
- link rel="preload" as="style" requests the stylesheet asynchronously.
- The onload attribute in the link allows the CSS to be processed when it finishes loading.
- "nulling" the onload handler once it is used helps some browsers avoid re-calling the handler upon switching the rel attribute.
- The reference to the stylesheet inside of a noscript element works as a fallback for browsers that don't execute JavaScript.
Solution 4
In addition to Fred's answer:
Solution using jQuery & Noscript
<html>
<head>
<style>
.blue{color:blue;}
</style>
<script type="text/javascript" src="../jquery-1.4.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
if($("body").size()>0){
if (document.createStyleSheet){
document.createStyleSheet('style.css');
}
else {
$("head").append($("<link rel='stylesheet'
href='style.css'
type='text/css' media='screen' />"));
}
}
});
</script>
</head>
<body>
<div class="blue">
Hello, world!
</div>
</body>
</html>
<noscript><link rel="stylesheet" href="small.css"></noscript>
from http://www.vidalquevedo.com/how-to-load-css-stylesheets-dynamically-with-jquery
Using pure Javascript & Noscript
<html>
<head>
<style>
.blue{color:blue;}
</style>
<script type="text/javascript">
var stylesheet = document.createElement('link');
stylesheet.href = 'style.css';
stylesheet.rel = 'stylesheet';
stylesheet.type = 'text/css';
document.getElementsByTagName('head')[0].appendChild(stylesheet);
</script>
</head>
<body>
<div class="blue">
Hello, world!
</div>
</body>
</html>
<noscript><link rel="stylesheet" href="small.css"></noscript>
Solution 5
Try this snippet
The author claims it was published by Google's PageSpeed Team
<script>
var cb = function() {
var l = document.createElement('link'); l.rel = 'stylesheet';
l.href = 'yourCSSfile.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>
![RafaSashi](https://i.stack.imgur.com/bK8em.jpg?s=256&g=1)
RafaSashi
About Rafasashi Web development primarily in php and javascript I am currently managing RECUWEB.COM an IT company providing webdesign, web development, digital marketing, advertising and hosting services all over the world. @rafasashi | Careers 2.0 | LinkedIn | Recuweb.com
Updated on July 24, 2022Comments
-
RafaSashi almost 2 years
I am trying to optimize the CSS delivery following the google documentation for developers https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery#example
As you can see in the example of inlining a small CSS file the critical CSS in inlined in the head and the original small.css is loaded after onload of the page.
<html> <head> <style> .blue{color:blue;} </style> </head> <body> <div class="blue"> Hello, world! </div> </body> </html> <noscript><link rel="stylesheet" href="small.css"></noscript>
My question regarding this example:
How to load a large css file after onload of the page?
-
RafaSashi over 10 yearsThanks for the jquery function I will definitely use it! For #2 the disable option has been removed from the tools in firefox up to version 23 and I had to use the about:conf entries. I confirm the css is loaded using noscript out from html.
-
Jayen about 10 yearsi'm confused at how the second one's javascript is different from just putting the
link
at the end of the head. -
RafaSashi over 8 yearsThe first solution requiers the jQuery library whereas the second one doesn't
-
Jayen over 8 yearsI'm not asking the difference between the first and second. The second doesn't wait for
DOMContentLoaded
so it seems to be the same as<link href="style.css" rel="stylesheet" type="text/css">
. -
Karim Samir over 8 years@Fred you have an error in your code it should be $("head").append('<link href="'+src+'" rel="stylesheet" type="text/css">');
-
Fred over 8 years@KarimSamir Back in the day, you needed to wrap it in $ to instantiate it as a DOM element. Not sure if this is still the case.
-
Huy Nguyen about 8 yearsI applied this technical and my homepage passed
Optimize CSS delivery
rule, however, this not work in details page, I use the same script because this script in layout file. -
Taylor D. Edmiston almost 8 years@Jayen Your statement is correct. It looks like current solutions accept the trade off of not deferring loading when JavaScript is disabled (under the assumption that it is hopefully uncommon).
-
Jonas T over 7 yearsSame here. It only optimize home page's CSS delivery rule. Doesn't work on all other page. any idea?
-
Jonas T over 7 yearsIt only solved home page's CSS delivery rule to 100/100. Doesn't work on all other page. any idea? Other pages are still showing "Eliminate render-blocking JavaScript and CSS in above-the-fold content" issue.
-
Raja Khoury over 7 yearsDid you check if other pages have additional stylesheets loaded ? Although i posted this answer I have never used this method. I load my CSS the old fashion way and try not to obsess with Google page speed score. Minify & optimize your css and work towards a better content to rank up.
-
rolu over 7 yearsI think the author modified it a bit: see developers.google.com/speed/docs/insights/OptimizeCSSDelivery
-
Sparky over 7 yearsIsn't having anything after a
</html>
tag invalid HTML? -
Shawn Rebelo about 7 yearsUsing either of that code actually reduces my score, not improve. Before using their "suggested defer code" Score: 77. After using (either one). Score: 69. So uh... no thanks.
-
authorandrew about 7 yearsThis solution works perfectly, but the loaded CSS file is never cached, meaning there's always an 'unstyled' flash before it loads. I am using critical CSS for very basic CSS, but it's still a very drastic change between the two. Any way to cache the file as it's dynamically loaded?
-
Don Dilanga over 5 yearsthis script may defer CSS, but it render blocks the page with jquery file.so it's not recommended as a good solution.
-
nulll over 4 years@authorandrew Chrome 80 works fine, on Firefox 74 there is the cache problem you mentioned
-
JAT86 almost 3 yearsMaybe using Base64 images (for small images like icons and logos) will help.
-
db2 over 2 yearsIt's 2021, using jQuery should not be the accepted answer.