ブラウザのCSS解釈方法についての衝撃事実

  • 68
    Like
  • 2
    Comment

CSSのパフォーマンスについて調査していたところ、衝撃の事実を知りました。
それは、

「CSSセレクタは右から左へと照合される」

らしいです。

今までの私の見解

.sample table td {
  color: red;
}

上記のようなコードがあったとき、以下の順序でブラウザは解釈・実行していると思っていました。
  1.  sampleクラスを見つける
  2.  1の子孫のtable要素を見つける
  3.  2の子孫のtd要素を見つける
  4.  文字色を赤くする

正しい見解

.sample table td {
  color: red;
}

上記のようなコードがあったとき、以下の順序でブラウザは解釈・実行しているらしいです。
  1.  全てのtd要素を見つける
  2.  1の先祖要素にtable要素が存在するかを確認
  3.  2のtable要素の先祖要素にsampleクラスが存在するかを確認
  4.  文字色を赤くする

このように、CSSセレクタは右から左へと照合されていきます。
※一番右側のセレクタは、キーセレクタと呼ばれるらしいです

何が問題か?

例えば、以下のようなHTMLコードがあったとします。

上記のCSSコードでsampleクラス配下の表の文字色を赤くしようとすると、まずDOM内の全てのtd要素を見つけ、さらにtable要素・sampleクラスの存在確認をしようとします。
sample2クラス配下の表は文字色が黒のままで良いので、sample2クラス配下のtd要素は、本来見つけなくて良いことになります。
これは、明らかなコストの無駄です。
sample2クラス配下のtd要素が爆発的に増えれば、パフォーマンス問題につながる可能性があります。

<!-- 文字色を赤くしたい表 -->
<div class="sample">
  <table>
    <tr>
      <td>hoge</td>
      <td>hogehoge</td>
    </tr>
    <tr>
      <td>fuga</td>
      <td>fugafuga</td>
    </tr>
  </table>
</dvi>

<!-- 文字色は黒のままで良い表 -->
<div class="sample2">
  <table>
    <tr>
      <td>hoge</td>
      <td>hogehoge</td>
    </tr>
    <tr>
      <td>fuga</td>
      <td>fugafuga</td>
    </tr>
  </table>
</div>

どのようにすべきだったか

既にお分かりかと思いますが、念のため記載しておきます。
やはり、文字色を赤くしたいセルにだけ、赤くするクラスを付与するのが一番良いです。

.red {
  color: red;
}
<!-- 文字色を赤くしたい表 -->
<div class="sample">
  <table>
    <tr>
      <td class="red">hoge</td>
      <td class="red">hogehoge</td>
    </tr>
    <tr>
      <td class="red">fuga</td>
      <td class="red">fugafuga</td>
    </tr>
  </table>
</dvi>

<!-- 文字色は黒のままで良い表 -->
<div class="sample2">
  <table>
    <tr>
      <td>hoge</td>
      <td>hogehoge</td>
    </tr>
    <tr>
      <td>fuga</td>
      <td>fugafuga</td>
    </tr>
  </table>
</div>

結論

  • キーセレクタはパフォーマンス問題に直結する可能性がある
  • キーセレクタは出来る限り絞り込む(無関係のDOMをマッチさせないようにする)
  • キーセレクタをどれだけ絞り込むかでコストが左右される

参考サイト

CSS の適用について
http://d.hatena.ne.jp/oknknic/20110716/1310835176

Webkit と Firefox のレンダリングの仕組み
https://www.html5rocks.com/ja/tutorials/internals/howbrowserswork/#Manipulating_the_rules_for_an_easy_match

レンダリングについて
https://qiita.com/mikimhk/items/7cfbd6c94d0f3d7aa51f#3-rendering