はじめに
Webのパフォーマンスチューニングについて調べていたりすると、ちょくちょく見かけるCSSOMという言葉。DOMのCSSバージョンなんだろうなぁと何となく理解したつもりになっていましたが、ふと気になって改めて調べなおしてみました。この記事ではCSSOMについての説明、そして、それに関連するパフォーマンスについてまとめてみます。
CSSOMとは
CSSOMは、CSS Object Modelを意味する略語であり、ブラウザでロードされたCSSのツリー構造を保持する仕組みです。例えば、body
にはこのスタイル、body
の下にあるdiv
には別のスタイル、というようなイメージですね。ブラウザは、このCSSのツリー構造をDOMに対して適用することで、上位のスタイルからより具体的な下位のスタイルへと連鎖的にスタイルを決定していきます。このようにして処理されたものはレンダリングツリーと呼ばれ、これに基いてレイアウトの計算処理と描画処理が行われます。
パフォーマンスにどう関係するの?
CSSOMがどのようにウェブのパフォーマンスへと影響を与えるのでしょうか。それは、CSSOMの構築はウェブページのレンダリングをブロックするという点です。言い換えると、CSSOMが構築されるまではウェブページには何も表示されず、ユーザの目にはただただ白い画面だけが映し出されます。そのため、CSSOMの構築に要する時間がUXへと影響を及ぼします。(より正確にはDOMとJavaScriptも含めてクリティカルレンダリングパスと呼び、コンテンツが描画されるまでに時間に影響します)
また、CSSOMはキャッシュという仕組みを持ちません。そのためCSSファイルをブラウザがキャッシュしていたとしても、リロードや別ページへの遷移が発生する度にCSSOMは再構築されることになります。なので、いくらキャッシュしていたとしても、巨大なCSSはCSSOMの構築に毎回時間をかけることになります。
CSSOMの処理を最適化するには?
CSSOMの処理パフォーマンスを上げるためには、以下のような方法が取られます。
複数のCSSファイルを1つのファイルにまとめる
CSSファイルが複数に分割されている場合、ブラウザは(HTTP/2でない限り)それぞれのファイルをダウンロードしなければいけません。そこでCSSファイルの内容をバンドラなどを使用して事前にまとめておけば、ダウンロードに要する時間を短縮することができます。
他のCSSファイルをインポートしない
CSSファイルをインポートすることは、パフォーマンスの低下につながります。以下のCSSを見てみましょう。
@import url("another-style.css")
この例では、CSSファイル内で@import
を使用することにより他のCSSを取り込んでいますが、ファイルをダウンロードするためのリクエストが別途発生してしまい、レンダリングをブロックしてしまいます。そのため、@import
を使用せず、上記と同じようにファイルをまとめておくのがベターです。
mediaを使用して必要な場合だけファイルを取得する
CSSの中には、モバイル機器にしか使われないスタイル定義、印刷時にしか使わないスタイル定義のように、特定の状況下のみで使用されるものがあります。そのようなケースで使用できるのが、<link>
要素のmedia
です。以下の例を見てみましょう。(Web Fundamentalsより引用)
<link href="style.css" rel="stylesheet">
<link href="print.css" rel="stylesheet" media="print">
<link href="other.css" rel="stylesheet" media="(min-width: 40em)">
この例では、style.css
に基本的なスタイル定義がしてあり、print.css
とother.css
には、特定の状況下でページを閲覧している場合のためのスタイル定義が含まれています。それぞれのmedia
で指定した条件を満たさない場合はレンダリングをブロックしないため、パフォーマンスを向上させることができます。
最後に
この記事ではCSSに焦点を当てて記述しましたが、パフォーマンス改善、つまりクリティカルレンダリングパスの短縮にはHTMLとJavaScriptを含めて総合的に判断する必要があります。
また、現状のサイトのパフォーマンスを簡易的に測定するには、以下のサービスやツールが役に立ちます。