Help us understand the problem. What is going on with this article?

ライブラリに頼らずに CSS の遅延読み込みを JavaScript で実現する

More than 3 years have passed since last update.

Google PageSpeed Insight から CSS の配信を最適化しなさいと怒られた場合、Above the fold のレンダリングに必要な CSS をインライン化して、残りの CSS を遅延読み込みする必要がある。その残りの CSS を遅延読み込みする JavaScript が長かったり、外部ライブラリ使ってリクエスト投げてたりしてたりするとイケてないので、短く書いてみたものをメモっとく。

OS X の Safari 9 と Chrome 49 と Firefox 45 で検証した程度なので使用は自己責任で!

Google のサンプルコード

Google のCSS の配信を最適化するに掲載されているコードの JavaScript 部分を引用。

<script>
var cb = function() {
    var l = document.createElement('link'); l.rel = 'stylesheet';
    l.href = 'small.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>

最新のブラウザのみに対応するようにコードを削減する

requestAnimationFrame の対応状況を Can I Use で確認する。

Screen Shot 2016-04-07 at 02.07.24.png

IE 9 を華麗にスルーして requestAnimationFrame は存在しているものだとする。

<script>
var cb = function() {
    var l = document.createElement('link'); l.rel = 'stylesheet';
    l.href = 'small.css';
    var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h);
};
requestAnimationFrame(cb);
</script>

コールバック関数は無名関数でそのまま渡してあげる。

<script>
requestAnimationFrame(function() {
    var l = document.createElement('link');
    l.rel = 'stylesheet';
    l.href = 'small.css';
    var h = document.getElementsByTagName('head')[0];
    h.parentNode.insertBefore(l, h);
});
</script>

document.headappendChild() でいいだろってことで短くしてみる。

<script>
requestAnimationFrame(function() {
    var l = document.createElement('link');
    l.rel = 'stylesheet';
    l.href = 'small.css';
    document.head.appendChild(l);
});
</script>

変数宣言は関数の引数で代用する。コードゴルフっぽくなってきた……。

<script>
requestAnimationFrame(function(l) {
    l = document.createElement('link');
    l.rel = 'stylesheet';
    l.href = 'small.css';
    document.head.appendChild(l);
});
</script>

最後に改行や空白を圧縮して1行にする。

<script>requestAnimationFrame(function(l){l=document.createElement('link');l.rel='stylesheet';l.href='small.css';document.head.appendChild(l)})</script>

1行80文字に収めたかったらこう。

<script>
requestAnimationFrame(function(l){l=document.createElement('link');
l.rel='stylesheet';l.href='small.css';document.head.appendChild(l)})
</script>

まとめ

ライブラリに頼らなくても自分で書けそう!

参考文献

https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery?hl=ja
http://caniuse.com

takuya0301
Mikatus 株式会社の VP Engineering 兼デザイングループグループリーダー。最近は Event Storming と Lagom に興味がある。
https://takuya0301.github.io
mikatus
税理士・会計事務所向けクラウドシステムの企画、開発、提供事業を行っております。
https://www.mikatus.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away