<link rel="preload" href="style.css" as="style" onload="this.rel='stylesheet'">
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'"
<noscript><link rel="stylesheet" href="stylesheet.css"></noscript>
- In the example above, we have used the preload attribute for Chrome, Safari, and Opera browsers to load the CSS file asynchronously.
- In the second line, we have used the “media=print” option for Firefox since it doesn’t use the “preload” browser hint.
- In the third line, we have used “noscript tag” with the same stylesheet for the browsers that don’t support the javascript. Onload event is a javascript-based event, so if the browser doesn’t use or support javascript, it can use the stylesheet file in the “NoScript tag”.
How can we load CSS Asynchronously? To load javascript with the async feature, only the “async” attribute is sufficient, but what about CSS? While the render-blocker resources are loaded by the browser, it prevents the browser from performing the rendering, painting, and placing actions on the page. For this reason, the users cannot perform the operations they want during the loading of the web page or they can see the important content of the page later than it should be. Loading CSS with the async feature is important in solving this problem and obtaining the “responsive loading” feature with user-centric performance metrics.
Why is Loading Asynchronously important?
Asynchronously, the loading of web resources by the browser during the creation of the web page allows the user to see the finished web page elements on the web page earlier. However, loading every resource asynchronously can create a bottleneck in the browser’s main thread. For this reason, it is important to determine which web page elements will be loaded in what order and whether asynchronously or synchronously. Asynchronously loading CSS Resources is important for speeding up the web page and developing web performance metrics to improve the user experience.
Which Web Page Performance Metrics and Core Web Vitals Metrics Can Be Improved by Loading CSS Async?
In the relationship between loading CSS Files as Async and opening web pages earlier for the user, some Pagespeed Metrics are more positively affected than others. Faster loading of CSS Files especially improves First Paint, First Contentful Paint, Largest Contentful Paint, and Speed Index metrics.
- Largest Contentful Paint is the moment the main content of a web page is loaded in the section above the fold.
- First Contentful Paint is the moment during the loading of a web page, a web page component is fully loaded.
- First Paint refers to the moment when the first pixel is painted during the loading of a web page.
Also, all of these metrics are being calculated in the above the fold section that is being visible to the user during the web page loading.
How to Load a CSS File in an HTML Document?
There are three different ways to upload CSS Files in an HTML Document.
- Inline CSS, loading CSS Codes in the “style” attribute within the HTML nodes.
- Internal CSS, loading CSS files in tags within the HTML Document.
- External CSS, loading CSS Files within the elements with external CSS file links.
To load CSS Files asynchronously, we need to use the external CSS files. To learn more about how to use CSS in HTML Documents, you can read our related guideline. And, if you don’t have enough information for “What is HTML“, you can read our related guideline.
How to Load CSS Files Asynchronously with Media Attribute?
The “media” attribute is used to upload CSS files asynchronously within the HTML Document. The media attribute specifies which media types the CSS file is valid for. When the “print” value is selected for the media attribute, the browser loads the relevant CSS file asynchronously. This is because we specify that the corresponding CSS file is for “printable” web page elements only. Therefore, the browser allows loading asynchronously, considering that the relevant CSS file is not of great importance. However, the “media = ‘print'” attribute and value pair prevents it from being used after the corresponding CSS file is loaded. For this reason, the CSS file related to the “onload event” of Javascript is loaded asynchronously. With “onload = ‘this.media =’ all ‘”, the CSS file is loaded asynchronous and it can be used without a render-blocker effect.
To load CSS Files async, you can check the code block below.
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'"
A Live Example of Async Loading of CSS Files
In Holisticseo.digital, we are planning to use GatsbyJS for better page speed, crawl efficiency and page experience via its virtual DOM. But before using GatsbyJS, in our wordpress version, we didn’t perform a page speed improvement yet. Thus, you can see how to load CSS files as async with a live example through Holisticseo.digital and its efficiency. Below, you will see an example
Holisticseo.digital’s CSS Files that can be loaded as async.
Below, you will see that how we used “media=’print” feature with onload event for our CSS files that are being meant in the Lighthouse report.
In Visual Studio Code, we have marked all CSS files with “media=’print’ onload=”this.media=’all'”.
We have checked all the CSS files for loading as asynchronously. But also, only loading the most important CSS files asynchronously can create more page speed improvement since it won’t create a CPU Bottleneck for the Browser’s Main Thread and also it will prioritize the most important CSS resource. Here, we have chosen to load all CSS files async because all of them touch to the above the fold section with style effects. You will see the result below.
We have decreased the syncrhonously loaded CSS file amount by 5.
The last CSS file is still being loaded as synchronously, because it couldn’t be finished during the loading of 6 different CSS file’s asynchronously loading phase. Thus, prioritizing the which CSS files should be loaded as asynchronously is important.
How to Audit and Determine Which CSS Files Should be Loaded as Async?
To audit and check which CSS files can be loaded asynchronously or which of them are being synchronously at the moment, you can use the methods below.
- Check which CSS Files are affecting which segment of the web page.
- Check the HTML Source Code to see how CSS Files are being loaded.
- Perform a Lighthouse Audit or use GTMetrix, Pingdom, Speedcurve.
- Perform experiments to see web pages’ changes in terms of performance while loading CSS files asynchronously.
CSS Files of Holisticseo.digital.
I recommend you to perform a manual check and then use the Lighthouse or other page speed test tools to see how CSS Files are being loaded.
What Does “Print” in “Media” Attribute Mean?
Print value for the media attribute means that the related source is only for the print-based media. Thus, a source file for the print-based media can only be used for the printable web page element. If you declare that a CSS file is only related to the printable media, browser can’t use it for the rest of the web page thus using the “print” value in the media attribute would be unnecessary unless you use onload event to turn its media value into the “all”. “All” value within the “media” attribute means that the related CSS file is a valid file for the all of the media types in the web page, thence it can be used for all of the web page after it is being loaded asyncrohonously.
Why you shouldn’t use faux media types for Loading CSS as Async?
To load CSS files asynchronously, some developers try to use “faux” media types. It means that they try to use “non-existing” or “non-valid” media types for making the files’ loading process faster.
Some browsers refuse to upload files containing faux media type or leave them to end. The reason for using media attributes to upload important CSS Files asynchronously is to allow the user to see the web page regarding the required style effects earlier. CSS files used with faux media type have the risk of not loading at all and may slow down the loading speed as they can be perceived as code errors by the browser. Also, resources with a faux media type may not be used by Search Engine Crawlers, such as Googlebot.
Can “preload” Browser Hint Help for CSS Loading as Asynchronously?
The browser hint feature called Preload tells the browser which resources to load first to create a web page. Thus, more important resources are loaded earlier, enabling the user to benefit from the web page earlier. However, as of Firefox 59, the preload feature is not supported for Firefox. Therefore, it is currently not possible to use the preload feature for Firefox to load CSS asynchronize. The preload feature supported by Chrome, Opera and Safari can be used to upload CSS files asynchronize as follows.
<link rel="preload" href="style.css" as="style" onload="this.rel='stylesheet'">
We have used preload browser hint to fetch the “style.css” file with the highest possible priority, after loading it asynchronously. We have turned its “rel” attribute’s value to the “stylesheet” again via the “onload” event so that browser can use it as a source for the web page’s styles.
How to Load CSS Asynchronously in Chrome and Firefox in the Best Possible Way?
To load CSS Files asynchronously in both Chrome and Firefox, we can use “preload” browser hint and “media=’print'” attribute along with onload event feature in a ordered way. you may use the codes below to load CSS Files without render-blocking resources features in Firefox and Chrome.
<link rel="preload" href="style.css" as="style" onload="this.rel='stylesheet'">
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'"
In this example above, we have used the preload feature first for the browsers that support it, later we have used the “media” attribute for asynchronous loading of CSS Files. Thence, if the browser supports the preload feature, it will use the first line of code only, if it doesn’t support the “preload” browser hint, then it will fetch the CSS file with the “print” media attribute and load it asynchronously.
How to Load CSS Files without Render Blocking Resources Effects with Javascript?
It is possible to upload CSS Files asynchronously with Javascript. For this, the relevant CSS file is added to a variable and inserted at the end of the head section with the help of Javascript. Since Javascript can be run as “async”, it is possible to load CSS Files with Javascript asynchronously. To load CSS files asynchronously without any kind of render-blocking resources effect, you can use the code example below.
var styleCSS= document.createElement("link");
styleCSS.rel = "stylesheet";
styleCSS.href = "style.css";
document.head.insertBefore(styleCSS, document.head.childNodes[document.head.childNodes.length - 1].nextSibling);
You may see the explanation of the code block above line by line.
- In the code block above, we have created a variable that stores the link element that we have created via the “document.createElement()” method.
- We have used “rel” method to specify the stylesheet as our “rel” value.
- We have used “href” method for specifying our CSS file’s URL and extension.
- We have inserted our CSS File that is being stored in “styleCSS” variable with its “stylesheet” and “style.css” values for “rel” and “href” attributes via “document.head.insertBefore()” method.
- We have inserted our CSS link element to the end of the head section of the HTML Document.
To load CSS files asynchronously by Javascript the code block above can be used.
Why Loading CSS Files Asynchronously via Javascript can have side-effects for Web Performance?
Thanks to Javascript, we can load CSS files asynchronously but since this Javascript code block will work in the “client-side rendering” principles, it will decrease its efficiency. The browsers will stop the rendering of the web page when they encounter these internal script tags, then they will render the javascript code to load the CSS asynchronously. Thus, the total rendering time of the web page can be longer than necessary.
Also changing a web page’s styles and final situation via Javascript is not recommended for the SEO. Client-side rendering of the web pages can make Googlebot and other Search Engine’s crawlers to have difficulties to see the final version of the web page while consuming the crawling and rendering resources. Googlebot and Bingbot are able to render the javascript but they don’t use rendering for every crawling process, thus sometimes they might miss the CSS files’ effects that are being loaded via Client-side rendering for the web pages and this can affect the quality score of the web pages in the perspective of Search Engine Algorithms.
Loading important CSS files via Javascript also can create a non-optimized resource load order since the related CSS file can be read at the end of the head section, probably some other resources will be already downloaded. That’s why using “preload” or “media=’print'” methodologies can be better for web performance and also crawl efficiency and budget.
What is LoadCSS.js Library and How to Use it for Asynchronous CSS?
The LoadCSS.JS library is a Javascript library created for CSS Files to be loaded asynchronously. In order for the relevant CSS Files to be loaded asynchronously, the “LoadCSS.js” file must first be uploaded on the web page. It can be loaded externally or internally in the head section. It is possible to manually insert a CSS into HTML Node asynchronously with the “loadCSS ()” function. Below is an example.
loadCSS("stylesheet.css");
In the code example above, if the loadCSS.js file is being downloaded to your computer, it will help the browser to download the CSS file asynchronously but since it is using client-side Javascript for inserting a stylesheet file to the HTML DOM, it is still not the best option. In the latest version of the “loadCSS.js” library, you can download a CSS file asynchronously as also below.
<link rel="preload" href="path/to/mystylesheet.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<script>
(function(){"Inlined loadCSS.js file"}());
</script>
In the code example above, you can use “loadCSS.js” in the head section as an internal script, this will guarantee that if the browser doesn’t support “preload”, it is still being downloaded as asynchronously. But still, using the “media=’print'” attribute with an onload event is the best option for loading CSS asynchronous for preventing render-blocking CSS problems to improve web page performance.
Why you should use the NoScript tag while loading CSS async?
Noscript tag ensures that if the browser doesn’t support the “javascript” still it can show the user the necessary content. To prevent users with old browsers to see a web page without actual content, using the NoScript tag as a fallback for Async CSS is important. You can see an example below.
<link rel="preload" href="style.css" as="style" onload="this.rel='stylesheet'">
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'"
<noscript><link rel="stylesheet" href="stylesheet.css"></noscript>
- In the example above, we have used the preload attribute for Chrome, Safari, and Opera browsers to load the CSS file asynchronously.
- In the second line, we have used the “media=print” option for Firefox since it doesn’t use the “preload” browser hint.
- In the third line, we have used “noscript tag” with the same stylesheet for the browsers that don’t support the javascript. Onload event is a javascript-based event, so if the browser doesn’t use or support javascript, it can use the stylesheet file in the “NoScript tag”.
Last Thoughts on Asynchronous CSS Loading and Holistic SEO
Uploading CSS Files asynchronously enables users to see and use the web page content faster while the web pages are loading. Loading Javascript files with Defer Attribute after DOMContentLoaded Event and ensuring asynchronously loading of Javascript Files with “Async attribute” is also to improve the user experience during the loading of the web page. It is important that the web page elements in the Largest Contentful Paint, which contains the most important part of the web page in particular, can be loaded and used faster for the user. It is therefore important to provide the necessary consultancy for async uploading of CSS Files in the scope of Holistic SEO, SEO Projects.
https://stackoverflow.com/questions/32759272/how-to-load-css-asynchronously
2020 Update – ASYNC LOADING
The simple answer (full browser support):
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'">
The documented answer (with optional preloading and script-disabled fallback):
<!-- Optional, if we want the stylesheet to get preloaded. Note that this line causes stylesheet to get downloaded, but not applied to the page. Use strategically — while preloading will push this resource up the priority list, it may cause more important resources to be pushed down the priority list. This may not be the desired effect for non-critical CSS, depending on other resources your app needs. -->
<link rel="preload" href="style.css" as="style">
<!-- Media type (print) doesn't match the current environment, so browser decides it's not that important and loads the stylesheet asynchronously (without delaying page rendering). On load, we change media type so that the stylesheet gets applied to screens. -->
<link rel="stylesheet" href="style.css" media="print" onload="this.media='all'">
<!-- Fallback that only gets inserted when JavaScript is disabled, in which case we can't load CSS asynchronously. -->
<noscript><link rel="stylesheet" href="style.css"></noscript>
Preloading and async combined:
If you need preloaded and async CSS, this solution simply combines two lines from the documented answer above, making it slightly cleaner. And again, as detailed in the documented answer above, preloading may not actually be beneficial.
<link href="style.css" rel="preload" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="style.css"></noscript>
Additional considerations:
Note that, in general, if you're going to load CSS asynchronously, it's generally recommended that you inline critical CSS, since CSS is a render-blocking resource for a reason.
Credit to filament group for their many async CSS solutions.
This approach may not work with content security policy enabled.
Follow
127k4242 gold badges242242 silver badges253253 bronze badges
answered Oct 15, 2017 at 1:32
41.5k88 gold badges5656 silver badges7373 bronze badges
3
There's no need to use loadCSS, the polyfill is enough: github.com/filamentgroup/loadCSS/blob/master/src/…
– nathan
1
Preload's spec status is finally [W3C Candidate Recommendation].(w3.org/TR/preload/…) Firefox supports it, but still disabled by default; click on answer's "widely supported" link for "Can I Use's" description of the Firefox flag that controls it.
1
Answer updated to provide solution for full browser support, along with additional explanation.
1
@jabacchetta the 2020 update is very much appreciated, thank you. I was looking specifically for instructions written in recent times where browser support is generally better. A lot changes over 3 years on the web!
– brandito
4
Apparently, it is better to
onload="this.rel='stylesheet'; this.onload = null"
. It is necessary to setthis.onload
tonull
to avoid this being called twice in some browsers, apparently.– Flimm
1
Doesn't play well for content security policy unfortunately.
– DGibbs
I looked at the code for "loadCSS.js", and it creates an artificial event "loadcssdefined", which it realizes via polling. Polling is generally considered an undesirable solution to problems, and is the antithesis of actual events. I will not be using "loadCSS.js".
– IAM_AL_X
<link href="style.css" rel="preload" as="style" onload="this.rel='stylesheet'">
does work in Firefox now– Flimm
Keep in mind that users with JS disabled will get the main CSS applied when printing, which may not be what you had in mind. This is why I prefer to use preload/prefetch and dynamically insert a link tag for main CSS instead of updating
print
toall
via JavaScript.– thdoan
148
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:
<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='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:
<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'"><noscript><link rel="stylesheet" href="css.css"></noscript>
You can see the operation in www.itcha.edu.sv
Source in http://keithclark.co.uk/
Follow
44.8k1515 gold badges109109 silver badges148148 bronze badges
answered Oct 28, 2016 at 22:48
5,35333 gold badges4444 silver badges4545 bronze badges
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.
– Teemoh
2
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?
2
Seems to still work for me. After doing this I know longer get a warning in PageSpeed Insights for this file.
3
this is working for me (08-july -2018) . And it giving good score in pagespeed insight
This works in staging/uat environments but not working in production environment. In production the css does not get applied at all even though the file is loaded. Any idea what could be causing this? I have tried it in multiple browsers
– Sahil
1
IMHO, jabachetta's newer answer using "preload", is likely the preferred solution now. If anyone has a reason to think this answer is still preferable, please add a comment explaining why. Ideally linking to a resource that confirms why/when this approach still might be preferable. [Assuming you use the polyfill to support
preload
on Firefox and on older browsers – see link in first comment of that answer].Why is the condition in
if (this.media != 'all') this.media = 'all'
necessary?– Flimm
@Flimm the statement you quoted is basically the entire solution — if you look at the
link
element, it'smedia
is set tonone
, effectively disabling it — the stylesheet will not apply to any kind of media, although the browser will download the resource. When the resource is thus downloaded, theload
event will fire, effectively executing the code specified as by theonload
attribute — which will switch applicable media value of the stylesheet to apply to all media, effectively enabling it. I can't say it will work though, just explaining the supposed intention.@amn I understand all of that. The part I don't understand is
if (this.media != 'all') this.media = 'all'
. Why not eliminate theif
condition, like this:this.media = 'all'
?– Flimm
Ah, I see — good point. Now that you brought it up, I wonder about that myself. I haven't tested the solution though.
This pattern may become invalid in the future. There's an open bug issue on Chromium that aims to not fetch a resource described by a
link
with an invalid media attribute, and a patch which is ready to but waiting for this pattern to disappear.– cdoublev
http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
###Dynamically loading an external JavaScript or CSS file
The conventional way to loading external JavaScript (ie: .js
) and CSS (ie: .css
) files on a page is to stick a reference to them in the HEAD section of your page, for example:
<head>``<script type=``"text/javascript"` `src=``"myscript.js"``></script>``<link rel=``"stylesheet"` `type=``"text/css"` `href=``"main.css"` `/>``</head>
Files that are called this way are added to the page as they are encountered in the page's source, or synchronously. For the most part, this setup meets our needs just fine, though in the world of synchronous Ajax design patterns, the ability to also fire up JavaScript/ CSS on demand is becoming more and more handy. In this tutorial, lets see how it's done.
Dynamically loading external JavaScript and CSS files
To load a .js or .css file dynamically, in a nutshell, it means using DOM methods to first create a swanky new "SCRIPT
" or "LINK
" element, assign it the appropriate attributes, and finally, use element.appendChild()
to add the element to the desired location within the document tree. It sounds a lot more fancy than it really is. Lets see how it all comes together:
function loadjscssfile(filename, filetype){
if (filetype=="js"){ //if filename is a external JavaScript file
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
}
else if (filetype=="css"){ //if filename is an external CSS file
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref)
}
loadjscssfile("myscript.js", "js") //dynamically load and add this .js file
loadjscssfile("javascript.php", "js") //dynamically load "javascript.php" as a JavaScript file
loadjscssfile("mystyle.css", "css") ////dynamically load and add this .css file
Demo:Load "myscript.js"Load "mystyle.css" | "myscript.js" source:var petname="Spotty" alert("Pet Name: " + petname) | "mystyle.css" source:#demotable td{ background-color: lightyellow; } #demotable b{ color: blue; } |
---|---|---|
Since external JavaScript and CSS files can technically end with any custom file extension (ie: "javascript.php
"), the function parameter "filetype
" lets you tell the script what file type to expect before loading. After that, the function sets out to create the element using the appropriate DOM methods, assign it the proper attributes, and finally, add it to the end of the HEAD section. Now, where the created file gets added is worth elaborating on:
document.getElementsByTagName(``"head"``)[0].appendChild(fileref)
By referencing the HEAD
element of the page first and then calling appendChild()
, this means the newly created element is added to the very end of the HEAD tag. Furthermore, you should be aware that no existing element is harmed in the adding of the new element- that is to say, if you call loadjscssfile("myscript.js", "js")
twice, you now end up with two new "SCRIPT
" elements both pointing to the same JavaScript file. This is problematic only from an efficiency standpoint, as you'll be adding redundant elements to the page and using unnecessary browser memory in the process. A simple way to prevent the same file from being added more than once is to keep track of the files added by loadjscssfile()
, and only load a file if it's new:
var filesadded="" //list of files already added
function checkloadjscssfile(filename, filetype){
if (filesadded.indexOf("["+filename+"]")==-1){
loadjscssfile(filename, filetype)
filesadded+="["+filename+"]" //List of files added in the form "[filename1],[filename2],etc"
}
else
alert("file already added!")
}
checkloadjscssfile("myscript.js", "js") //success
checkloadjscssfile("myscript.js", "js") //redundant file, so file not added
Here I'm just crudely detecting to see if a file that's set to be added already exists within a list of added files' names stored in variable filesadded
before deciding whether to proceed or not.
Ok, moving on, sometimes the situation may require that you actually remove or replace an added .js or .css file. Lets see how that's done next.
- Dynamically removing an external JavaScript or CSS file
- Dynamically removing/ replacing external JavaScript and CSS files, conclusion
Dynamically removing/ replacing external JavaScript and CSS files, conclusion