Optimize CSS asynchronous load

One of way to make website loading faster is CSS async load.
It need to use Javascript to load CSS after loading.

There’s a few steps to make it work.

1. Make css file to Json data format.
Let’s take this css file for example.
http://file.myfontastic.com/eNzJBJA24QdpMtRZDEqjmX/icons.css
It contains css code like this.

@charset "UTF-8";

/* untitled-font-1 */
@font-face {
  font-family: "untitled-font-1";
  src:url("https://file.myfontastic.com/eNzJBJA24QdpMtRZDEqjmX/fonts/1491933871.eot");
  src:url("https://file.myfontastic.com/eNzJBJA24QdpMtRZDEqjmX/fonts/1491933871.eot?#iefix") format("embedded-opentype"),
    url("https://file.myfontastic.com/eNzJBJA24QdpMtRZDEqjmX/fonts/1491933871.woff") format("woff"),
    url("https://file.myfontastic.com/eNzJBJA24QdpMtRZDEqjmX/fonts/1491933871.ttf") format("truetype"),
    url("https://file.myfontastic.com/eNzJBJA24QdpMtRZDEqjmX/fonts/1491933871.svg#1491933871") format("svg");
  font-weight: normal;
  font-style: normal;
}

[data-icon]:before {
  font-family: "untitled-font-1" !important;
  content: attr(data-icon);
  font-style: normal !important;
  font-weight: normal !important;
  font-variant: normal !important;
  text-transform: none !important;
  speak: none;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
.
.
.

 

Let’s minify it from cssminifier.com

@charset "UTF-8";[class*=" icon-"]:before,[class^=icon-]:before,[data-icon]:before{font-family:untitled-font-1!important;font-style:normal!important;font-weight:400!important;font-variant:normal!important;text-transform:none!important;speak:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@font-face{font-family:untitled-font-1;src:url(https://file.myfontastic.com/eNzJBJA24QdpMtRZDEqjmX/fonts/1491933871.eot);src:url(https://file.myfontastic.com/eNzJBJA24QdpMtRZDEqjmX/fonts/1491933871.eot?#iefix) format("embedded-opentype"),url(https://file.myfontastic.com/eNzJBJA24QdpMtRZDEqjmX/fonts/1491933871.woff) format("woff"),url(https://file.myfontastic.com/eNzJBJA24QdpMtRZDEqjmX/fonts/1491933871.ttf) format("truetype"),url(https://file.myfontastic.com/eNzJBJA24QdpMtRZDEqjmX/fonts/1491933871.svg#1491933871) format("svg");font-weight:400;font-style:normal}[data-icon]:before{content:attr(data-icon)}.icon-chevron-right:before{content:"\61"}.icon-chevron-left:before{content:"\62"}.icon-twitter-alt:before{content:"\64"}.icon-youtube:before{content:"\63"}.icon-facebook:before{content:"\65"}.icon-pinterest-circled:before{content:"\66"}.icon-search:before{content:"\69"}.icon-star-1:before{content:"\6b"}.icon-instagram:before{content:"\6c"}.icon-rss:before{content:"\68"}.icon-googleplus:before{content:"\67"}.icon-pinterest:before{content:"\6a"}.icon-remove:before{content:"\6d"}.icon-arrow-circle-right:before{content:"\6e"}.icon-bars:before{content:"\6f"}.icon-share-alt:before{content:"\70"}

It became much smaller.
Using editor, escape backslash (\) like this (\\). And then escape double quote (“) to (\”). Also escape slash (/) to (\/)

Then it will look like this.

@charset \"UTF-8\";[class*=\" icon-\"]:before,[class^=icon-]:before,[data-icon]:before{font-family:untitled-font-1!important;font-style:normal!important;font-weight:400!important;font-variant:normal!important;text-transform:none!important;speak:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@font-face{font-family:untitled-font-1;src:url(https:\/\/file.myfontastic.com\/eNzJBJA24QdpMtRZDEqjmX\/fonts\/1491933871.eot);src:url(https:\/\/file.myfontastic.com\/eNzJBJA24QdpMtRZDEqjmX\/fonts\/1491933871.eot?#iefix) format(\"embedded-opentype\"),url(https:\/\/file.myfontastic.com\/eNzJBJA24QdpMtRZDEqjmX\/fonts\/1491933871.woff) format(\"woff\"),url(https:\/\/file.myfontastic.com\/eNzJBJA24QdpMtRZDEqjmX\/fonts\/1491933871.ttf) format(\"truetype\"),url(https:\/\/file.myfontastic.com\/eNzJBJA24QdpMtRZDEqjmX\/fonts\/1491933871.svg#1491933871) format(\"svg\");font-weight:400;font-style:normal}[data-icon]:before{content:attr(data-icon)}.icon-chevron-right:before{content:\"\\61\"}.icon-chevron-left:before{content:\"\\62\"}.icon-twitter-alt:before{content:\"\\64\"}.icon-youtube:before{content:\"\\63\"}.icon-facebook:before{content:\"\\65\"}.icon-pinterest-circled:before{content:\"\\66\"}.icon-search:before{content:\"\\69\"}.icon-star-1:before{content:\"\\6b\"}.icon-instagram:before{content:\"\\6c\"}.icon-rss:before{content:\"\\68\"}.icon-googleplus:before{content:\"\\67\"}.icon-pinterest:before{content:\"\\6a\"}.icon-remove:before{content:\"\\6d\"}.icon-arrow-circle-right:before{content:\"\\6e\"}.icon-bars:before{content:\"\\6f\"}.icon-share-alt:before{content:\"\\70\"}

Let’s wrap this with this javascript function. callbackCSS({"data":"json content goes here"})

Final myfontastic.json file look like this.

callbackCSS({"data":"@charset \"UTF-8\";[class*=\" icon-\"]:before,[class^=icon-]:before,[data-icon]:before{font-family:untitled-font-1!important;font-style:normal!important;font-weight:400!important;font-variant:normal!important;text-transform:none!important;speak:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@font-face{font-family:untitled-font-1;src:url(https:\/\/file.myfontastic.com\/eNzJBJA24QdpMtRZDEqjmX\/fonts\/1491933871.eot);src:url(https:\/\/file.myfontastic.com\/eNzJBJA24QdpMtRZDEqjmX\/fonts\/1491933871.eot?#iefix) format(\"embedded-opentype\"),url(https:\/\/file.myfontastic.com\/eNzJBJA24QdpMtRZDEqjmX\/fonts\/1491933871.woff) format(\"woff\"),url(https:\/\/file.myfontastic.com\/eNzJBJA24QdpMtRZDEqjmX\/fonts\/1491933871.ttf) format(\"truetype\"),url(https:\/\/file.myfontastic.com\/eNzJBJA24QdpMtRZDEqjmX\/fonts\/1491933871.svg#1491933871) format(\"svg\");font-weight:400;font-style:normal}[data-icon]:before{content:attr(data-icon)}.icon-chevron-right:before{content:\"\\61\"}.icon-chevron-left:before{content:\"\\62\"}.icon-twitter-alt:before{content:\"\\64\"}.icon-youtube:before{content:\"\\63\"}.icon-facebook:before{content:\"\\65\"}.icon-pinterest-circled:before{content:\"\\66\"}.icon-search:before{content:\"\\69\"}.icon-star-1:before{content:\"\\6b\"}.icon-instagram:before{content:\"\\6c\"}.icon-rss:before{content:\"\\68\"}.icon-googleplus:before{content:\"\\67\"}.icon-pinterest:before{content:\"\\6a\"}.icon-remove:before{content:\"\\6d\"}.icon-arrow-circle-right:before{content:\"\\6e\"}.icon-bars:before{content:\"\\6f\"}.icon-share-alt:before{content:\"\\70\"}"})

And define this javascript function on the top of your page. You can include this in common javascript file on the header.

var LSYE=function(h){var s=document.createElement('script');s.src=h;document.getElementsByTagName('head')[0].appendChild(s);};
var callbackCSS=function(d){var o=document.createElement("style");o.innerHTML=d.data;document.getElementsByTagName('head')[0].appendChild(o);};

LYSE function is put javascript to header async way.
And callbackCSS will put css data to header after that.

So you can put this line at the bottom of page, this css will be loading asynchronous way.

<script>LSYE("myfontastic.json");</script>

You can add async attribute to loading file during page load.

<script async>LSYE("myfontastic.json");</script>

Or add defer attribute to loading file after page load finished.

<script async>LSYE("myfontastic.json");</script>

In my case, this css file contains icons for the site. So icons are appeared just few seconds later, but shows totally fine.
This will be helpful when the file is not loading or slow. So this doesn’t affect to site speed.