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