Reputation: 146
I have a critcal CSS process in place that prevents a flash-of-unstyled-content (FOUC) on above-the-fold content of a page.
I'm stuck on 'defer unused CSS' point that's being highlighted by Google PageSpeed insights (lighthouse) and/or Chrome's Performance Audit.
I've gone through other articles but they do not work.
To summarize I've tried so far.
Ref: CSS delivery optimization: How to defer css loading?
If I delay loading the script via setTimeout
by a fixed time of 3 seconds the 'defer unused CSS' issue goes away.
3 seconds is what's needed for Google PageSpeed Insights test (mobile) as they are slower devices but 3 seconds is a lot for desktops which generally has more processing power (note, not always true, hence excluding user-agent based logic).
So the question boils down to how do I delay loading the CSS by the least amount of time irrespective of the device type or specs.
Feel free to throw any rough ideas, I'll try them out and report back, if your idea works, we'll update the code and mark your answer has the chosen one.
Next on my list to try is requestAnimationFrame
+ small fixed delay.
Upvotes: 2
Views: 1912
Reputation: 146
Manually loading a CSS based on two triggers, whichever occurs first.
<script>
var raf = requestAnimationFrame || mozRequestAnimationFrame ||
webkitRequestAnimationFrame || msRequestAnimationFrame;
var app_css_loaded = false;
/* console.log(performance.now() + ' - ' + '1. async css script init'); */
var loadAppCss = function(){
if(!app_css_loaded) {
app_css_loaded = true;
var l = document.createElement('link'); l.rel = 'stylesheet';
l.href = 'YOUR_COMBINED_AND_MINIFIED_CSS_HERE.css';
var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h);
/* console.log(performance.now() + ' - ' + '5. script injected'); */
}
};
var cb = function() {
/* console.log(performance.now() + ' - ' + '3. cb called'); */
setTimeout(function(){
/* console.log(performance.now() + ' - ' + '4. timeout start'); */
loadAppCss();
/* console.log(performance.now() + ' - ' + '6. timeout end'); */
}, 3000);
};
window.addEventListener('load', function(){
/* console.log(performance.now() + ' - ' + '2. triggering cb directly'); */
if(raf) { raf(cb); } else { cb(); };
});
var loadAppCssOnScroll = function(){
/* console.log(performance.now() + ' - ' + '### triggering cb on scroll'); */
window.removeEventListener('scroll', loadAppCssOnScroll);
if(raf) { raf(loadAppCss); } else { loadAppCss() };
};
window.addEventListener('scroll', loadAppCssOnScroll);
</script>
This makes the PageSpeed insights recommendation regarding defer unused CSS go away.
requestAnimationFrame, if available, will stall the CSS file from loading if the tab has opened in the background in most browsers. You could remove it from the above code if it does not meet your requirements. Ref
console.log() is not available in all browsers. Do not use it in production. Ref
Upvotes: 1