rcmdnk's blog

Web制作者のためのCSS設計の教科書 モダンWeb開発に欠かせない「修正しやすいCSS」の設計手法

Googleの PageSpeed Insights で見ると スクロールせずに見えるコンテンツのレンダリングをブロックしている JavaScript/CSS を排除する という項目が出ててCSSファイルがブロックしてる様なので それをなんとかしよう、と言う話。

これまでの設定

これまでCSSファイルはsassで書いたものをまとめた /stylesheets/screen.cssとFontAwesome の物をhead内で呼んでました。

<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<link href="{{root_url}}/stylesheets/screen.css" media="screen, projection" rel="stylesheet">

</body> 前に持ってってみる

これが上にあるのがダメなので、JavaScriptとかでよくやるみたいに 下に持って行ってさらに非同期で読み込むようにしてみます。

source/_incldues/after_fotter.htmlなんかに

after_footer.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script type="text/javascript">
(function (d) {
  var j, s = d.getElementsByTagName('script')[0];
  a = function (u, i) {
    if (!d.getElementById(i)) {
      j = d.createElement('link');
      j.rel = 'stylesheets';
      j.href = u;
      if (i) {j.id = i;}
      s.parentNode.insertBefore(j, s);
    }
  };
  a("//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css","font-awesome-css");
  a("{{root_url}}/stylesheets/screen.css","screen-css");
})(document);
</script>

な感じで書きます。

ここでIDもこの様に指定しておけば、 head内で

<link href="{{root_url}}/stylesheets/screen.css" media="screen, projection" rel="stylesheet" id="screen-css">

と書いた時に再度読み込むことを避ける事が出来ます。

取り敢えずこれでやってみたところ、 最初の表示が崩れて表示されるのと、全部読み込んだ後でもページ中におかしな表示が残る様になってしまいました。

JavaScriptで後からいじる部分とかがあるので、最初にきちんとscreen.cssの方が読み込まれてないとダメみたいです。

インライン化を試してみる

PageSpeed InsightのCSS の配信を最適化する を参照すると、 スクロールせずに見える範囲(Above the fold)のコンテンツに関するCSSだけを抜き出して head内にインラインで書き、 本体のscreen.cssとかは </html>の下に書けば良い、とのこと。

この様な部分を自分で探して抜き出すのは結構大変ですが、 世の中には色々便利なツールがあります。

addyosmani/critical-path-css-tools

ここにある色々なツールで自分のサイトのAbove the foldな部分の CSSを抜き出すことが出来ます。

試しにウェブサービスになってる

Critical Path CSS Generator - by Jonas Ohlsson

で試してみると、 元が59180文字だったのが9665抜き出されました。 6分の1位。

この部分だけ取り敢えず他のファイルに書いてheadで読み込んで、 screen.cssだけ下に持って行ってみましたが、 やはり途中で上手く行かないところがあります。

ちょっとページのJavaScriptとか細かいところまで見て 特にページの中の大きさとか決めてる物はAbove the foldに無いところでも 持ってこないとダメそう。

それにはちょっとSCSS全部を整理しないといけないのでちょっと今回は断念。

使ってないCSSの削除

また、上のリンク集の中に UnCSS というツールがあって、これをかけると実際に使われてるものだけを取ってきてくれる物があります。

こちらのツールはページ全体を読んで 使われてる物を探してきている様ですが、 インプットの指定がいまいち分からず、FontAwesomeとかGoogle検索のCSSとか 全部入りの状態でトップページを見てみたところ、 30000文字程度だったので、 screen.cssだけで6万文字近くあるのを考えると大分無駄がありそうです。。。 とは言っても他にコードのあるページとかだとここでは使ってないものもありますし、 全ページで使われてる物をきちんと抜き出すのは結構大変そうです。

これもそのうち気が向いたらリストへ。

FontAwesomeだけ下に持っていく

FontAwesomeは単に記号の置き換えをしてるだけなので ページの組み立てにはそれ程影響がありません。

なので上のスクリプトでFontAwesomeだけにして、 screen.cssだけhead内に残す様にしてみました。

するとPageSpeed Insightでも スクロールせずに見えるコンテンツのレンダリングをブロックしている JavaScript/CSS を排除する の部分からFontAwesomeは消えて修正が必要から修正を考慮の項目に移すことが出来ました。

表示も気持ち速くなった感じ。 (キャッシュも効いてたりするので見た目では分かりづらいですが、 これらに関してはちゃんと測ったりはしてないです。)

JavaScriptを全部後ろに持って行ってscreen.cssもその直前に

JavaScriptの方も色々と整理していて、 全部のスクリプトを</body>前に持って行くことが出来たので、 その前でscreen.cssを読めばよいか、ということで 上の例の様な非同期にしないで、</body>前で直接

<link href="{{root_url}}/stylesheets/screen.css" media="screen, projection" rel="stylesheet">

と呼んでJavaScriptを呼ぶ様なこともしてみました。

すると今度は

表示可能コンテンツの優先順位を決定する

スクロールせずに見えるコンテンツをレンダリングするには、追加でネットワークのラウンド トリップが必要です。最適なパフォーマンスを得るには、スクロールせずに見えるコンテンツをレンダリングするのに必要な HTML の量を減らしてください。 スクロールせずに見えるコンテンツをレンダリングするには 49.2 KB の HTML レスポンスが必要でした。このためにはネットワーク ラウンドトリップが 3 回必要となります。最初の 2 回のラウンドトリップ分の HTML のみでレンダリングできるよう、スクロールせずに見えるコンテンツの優先順位を決定してください。 2 回以内のラウンドトリップでの HTML 配信で、最後のスクロールせずに見えるコンテンツの約 6% のみレンダリングできました(スクリーンショットを見る)。

みたいな警告が。

これはいわゆるFOUC(Flash of Unstyled Content)問題 1 だと思うんですが、HTMLを一度 レンダリングしてしまってから CSSを見つけて再びレンダリングする、みたいな作業になってしまって 余計な負荷がかかってしまってる様子。

なのでやはりページの枠組みを作ってる様なCSSの部分は前に残さないとダメだな、と。

その他参考

今回色々やるにあたって参考になったページ。

2.2 Above the fold CSS: http://patrickhamann.com/workshops/performance/tasks/2_Critical_Path/2_2.html

Above the foldやUnCSSについても書いてあります。 Above the foldに関しては ブックマークレット が紹介されてますが、このブックマークレットは Firefoxでは動かないのでGoogle Chromeとかで使う必要がありました。

また、さらに最後に basket.js(addyosmani/basket.js というJavaScriptが紹介されています。

これは一度取ってきたスクリプトとかをブラウザのキャッシュの代わりにローカルストレージ(localStorage)に 保存して次からそれを読み出す、と言う事を行ってくれるスクリプトです。

ブラウザとか環境にも依りますが、大体の場合キャッシュの方が 速いみたいですが2、 例えばサーバー側でキャッシュの設定とかを出来ない環境とかだとより有効なのかな、と。 今後、この辺のブラウザの仕様も変わっていくのかも知れませんが。

GitHub Pagesだと.htaccessでキャッシュの有効時間とかの設定を変えたり出来ないので3、 コレ使えるかな、とも。

ただ、頻繁にページを見ない限りは逆にこのスクリプトを読む分だけ 遅くなってしまうし、 後、CSSの場合はちょっと面倒4な感じなのでCSSには使うことは試してません。

まとめ

最終的にscreen.cssに関してはそのままhead内に残し、 FontAwesomeのものだけafter_footer.htmlの中で非同期で呼ぶ様な スクリプトで読み込む様にしました。

FontAwesomeが他の物をブロックしなくなった分だけちょっとは良くなったかな、と。 ただ、FontAwesomeはそもそも一部しか使ってないので UnCSSとか使って出てきたものだけを使うのもありかな、とも。 (そうすると便利さが半減しますが。)

screen.cssの方も整理する事が必要な感じなので、 ちょっとずつ見ていこうとは思います。

Sponsored Links
Sponsored Links

« ソーシャルボタンの数をビルド時に取ってくる サイドバーのランダムリストのアップデート »

}