読者です 読者をやめる 読者になる 読者になる

kitak.blog

Kみたいなエンジニアになりたいブログ

クリティカルCSS 雑感

t32kさんの Smashing Magazineのパフォーマンス改善ケースが凄まじい件 - MOL の記事を読んで、クリティカルCSSが気になったので少し調べてみました。それの雑感。

クリティカルCSSとは

一言でいうと、ページのATF(Adove The Fold)の表示に必要なスタイルシートのこと。 これをインラインでHTMLに埋め込むことによって、クリティカルレンダリングパスの最適化を図る。
クリティカルレンダリングパスについては、Critical Rendering Path — Web Fundamentals、クリティカルCSSについては、上の記事 や そろそろクリティカルCSSについて説明しておこうか | Yuhiisk で詳しい説明がされている。

クリティカルCSSによって削減できる時間

不要なスタイルシートの記述があると表示にかかる時間が増える、というのは、感覚としてなんとなくは理解できるけど、もう少しブラウザの仕組みに踏み込んで、どの時間が削減できるのか考えてみた。

  • 大きな一塊の外部スタイルシートの取得にかかる時間
  • ATFの表示には不要なものを含んだCSSOMを構築する時間
  • DOMと↑のCSSOMを使ってスタイルを解決し、レンダーツリーを構築する時間

こんなところですかね、憶測で言っております。
今日(というのはNavigation Timing API v2が数年後に控えているためです)では、以下の内容をクリティカルCSSの適用前後で計測することで、改善の成否を判断することになると思います。

  • Navigation Timing API のタイムスタンプ domContentLoaded と domLoading の差
    • domContentLoadedはDOMとCSSOM両方の準備が整ったタイミング、この後レンダーツリーが構築される
    • CSSOMの構築にかかる時間が減ったかどうか分かる
  • API のタイムスタンプ domComplete と domContentLoaded の差
    • domCompleteは画像などのリソースの取得の完了とかも含まれるので微妙だが...
    • レンダーツリーの構築にかかる時間が減ったかどうか分かる
  • Chrome, Opera, IE11 に限定されるが、firstPaintTime (APIは、ChromeOperaとIE11、それぞれ独自のもの)
    • 最終的に表示にかかる時間が短くなったかどうか分かる

他に、WebPagetest - Website Performance and Optimization Testで算出される指標(Start Render, Speed Index)を参考にするのもよさそう。

ツール・運用

クリティカルCSSの生成は、pocketjoso/penthouse · GitHub, addyosmani/critical · GitHub, filamentgroup/criticalCSS · GitHub あたりのツールを使う。HTMLテンプレートを指定する形式、対象のページのURLを指定する形式など、仕様が異なるので、自分に適したものを選択する。

HTMLやCSSファイルが変更されるたびにクリティカルCSSの生成、HTMLへの埋め込みを行わないといけないので運用はかなり面倒。上にあげたツールはコマンドを提供しているが、毎回、手でポチポチやるのは面倒くさいので、タスクを一回叩くことで生成・埋め込みまでできるようにしておくべき。gulpプラグインインターフェイスを提供しているツールもある。

適用すべきか否か

上で書いたように運用が面倒なので、それに見合ったメリットがあるかをあるか考慮する。
サイトの表示スピードが売上・会員登録数などに直結していて、表示にかかる時間を可能なかぎり短くしたい場合に適用を検討する。

元々ページで読み込んでいたCSSのサイズが小さい・ページの規模が小さい場合は、ブラウザのリソースプリロード機能によってスタイルシートの取得が最適化されていたり、CSSOM・レンダーツリーの構築コストも小さいので、使う必要はないと判断する。
いっそのこと、HTMLのサイズが大きくなりすぎないレベル(ひとつの基準としてTCPのデフォルトウィンドウサイズの17KB)で全てインラインにしてしまう(元々読み込んでいたCSSのサイズとクリティカルCSSのサイズの差が小さい場合も同様)。

個人的に、以下のケースで適用を考えています。

  • モバイルのハイブリッドアプリ
    • 表示にかかる時間を可能なかぎり短くして、ネイティブアプリと遜色ない体験を与える
    • 局所的に起動時のローディングの表示を最適化する
  • Single Page Application
    • Single Pageという性質上、読み込むCSSファイルが大きな一塊のものになりがち
    • ハイブリッドアプリ同様にローディングの表示の最適化
  • ECサイトの商品・決済ページ
    • 売上に直結する
  • 縦長のレスポンシブデザインのスマホサイト
    • ATFではない領域が大きいので、クリティカルCSSが生きる
    • デスクトップ環境を想定した不要なスタイルを読み込む必要がない

HTTP/2

将来的にHTTP/2が普及すれば、

  • 通信の多重化により、現在のCSSファイルを結合・圧縮するプラクティスが不要になる
  • サーバープッシュでCSSファイルを事前に送ってキャッシュできる

ので、サイトのアーキテクチャによっては、クリティカルCSSは不要になるかもしれない。
あるいはクリティカルCSSを外部スタイルシートとしてサーバーで配信して、サーバープッシュで送る、というやり方もHTMLにインラインで埋め込むという手間が省けるのでありかもしれない(省いた分を他所で担っているので、どっこいどっこいな気もしますが)。