Skip to content

Instantly share code, notes, and snippets.

@matheusd
Created May 24, 2017 20:25
Show Gist options
  • Save matheusd/01aeb085000000fece2898875122a30c to your computer and use it in GitHub Desktop.
Save matheusd/01aeb085000000fece2898875122a30c to your computer and use it in GitHub Desktop.
Optimzed CSS download for my website
minified css file with below-the-fold styles that will be separately loaded
minified css file with @import and @font-face rules
<!DOCTYPE html>
<html>
<head>
<!-- theme's head partial -->
<!-- ... -->
<style>{{- readFile "/themes/matheusd/static/css/style.css" | safeCSS -}}</style>
<script>{{- readFile "/themes/matheusd/static/js/MDWSLoader.js" | safeJS -}}</script>
<script>
MDWSLoader.setCSS([
'{{ "/css/fonts.css" | absURL }}',
'{{ "/css/extra-styles.css" | absURL }}',
'//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css'
]);
MDWSLoader.checkOnHead();
</script>
</head>
<body>
<script>
MDWSLoader.checkOnStartBody();
</script>
/** My dynamic CSS loader for embedding. */
(function () {
var MDWSLoader = {
/** Sets the CSS files used by the system. */
setCSS: function (files) {
this.cssFiles = files;
},
/** Load the css files using document.write(link...). */
writeCSS: function () {
for (var i = 0; i < this.cssFiles.length; i++) {
document.write("<link rel='stylesheet' href='" + this.cssFiles[i] + "'>");
}
},
/** Checks if it's likely that the css files are on cache and we can inject it at the head
* to prevent FOUT/FOIT.
*/
shouldRevalidateFont: function () {
var str = localStorage.getItem("dtLastFontLoad");
if (!str) return true;
var dtVisit = parseInt(str);
var dtNow = Math.floor((new Date()).getTime() / 1000);
return Math.abs(dtNow - dtVisit) > 86400;
},
/** Performs the check at the end of the HEAD section */
checkOnHead: function () {
if (!this.shouldRevalidateFont()) {
this.writeCSS();
}
},
/** Performs the check at the start of the body. */
checkOnStartBody: function () {
if (!this.shouldRevalidateFont()) {
console.log('adding on start body');
this.addFontLoadedClassToBody();
}
},
/** Performs the check at the end of the body. */
checkOnEndBody: function (fontToWatch) {
if (this.shouldRevalidateFont()) {
this.setupFontWatcher(fontToWatch);
this.writeCSS();
}
},
/** Adds the fontsLoaded class to the body element. */
addFontLoadedClassToBody: function () {
document.getElementsByTagName("body")[0].classList.add("fontsLoaded");
},
/** Async load and setup the font watcher. */
setupFontWatcher: function (fontToWatch) {
var e = document.createElement("script");
e.src = "https://cdnjs.cloudflare.com/ajax/libs/fontfaceobserver/2.0.9/fontfaceobserver.standalone.js";
e.async = true;
var that = this;
e.onload = function () {
var font = new FontFaceObserver(fontToWatch);
font.load().then(function () {
console.log('font found');
localStorage.setItem("dtLastFontLoad", Math.floor((new Date()).getTime() / 1000) );
that.addFontLoadedClassToBody();
}, function () {
console.log('Font is not available');
});
};
document.getElementsByTagName("body")[0].appendChild(e);
}
};
window['MDWSLoader'] = MDWSLoader;
})();
minified css file with above-the-fold styles that will be directly embedded in page
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment