WebページのHTMLサイズを縮小しようとしているときに、GoogleとPageSpeed FirefoxアドオンによるCSSセレクターの効率の再調整に関する提案に出くわしました。これにより(ほぼ)変更を再考することができました。
http://code.google.com/intl/de-DE/speed/page-speed/docs/rendering.html#UseEfficientCSSSelectors
特に、子孫セレクターは、IDまたはCLASS属性を使用してブロック全体(DIVなど)を選択し、そのすべての子要素にCLASS/ID属性がないようにするのに最適です。ただし、ルールを適用するためのトラバーサルの順序がGoogleの説明どおりである場合は、それらを使用しないでください。
子孫セレクターは非効率的です。これは、キーに一致する要素ごとに、ブラウザーがDOMツリーをトラバースし、一致する要素が見つかるかルート要素に到達するまですべての祖先要素を評価する必要があるためです。キーの具体性が低いほど、評価する必要のあるノードの数が多くなります。
ブラウザがこのような非効率的なトラバーサルの順序を使用していることは非常に疑わしいです。確かに、ブラウザは最上位のセレクタコンポーネントに一致する要素のサブツリーのみを処理します。つまり、#foo span {...}
すべてのスパンではなく、#fooより下の要素のみをチェックする必要があります。最近のブラウザコードを見た人は誰でもこれを確認/拒否できますか?
2番目の疑わしい提案は、過度に修飾されたセレクターに関するものです。
IDセレクターは定義上一意です。タグまたはクラス修飾子を含めると、不必要に評価する必要のある冗長な情報が追加されるだけです。
IDセレクターが定義上一意である場合、ブラウザーが冗長な情報をチェックする必要があるのはなぜですか?私は彼らがそうすることを知っています、例えば、
div#foo {色:黒; } #foo {色:白; }
に黒いテキストが表示されますが<div id=foo>
、a)実行しないでください(?W3C参照が必要です)b)要素の単純なO(1)チェックが発生したときに、なぜ著しく遅くなるのかわかりませんタグ名。
現代のブラウザのソースコードと仲良くしている人は、これらの主張に光を当てることができますか?最近のほとんどのサイトは子孫セレクター(SOを含む)を使用しており、それらには明らかな利点があるので、私はそれらを使用したいと思います...
編集:
生成されたページで少し実験しましたが、ブラウザーによる子孫セレクターの処理は確かに哀れなようです。
(省略形)で構成されるページ:
#top a {text-decoration:none;}
#foo1 a.foo {色:赤;}
#foo2 a.foo {色:赤;}
[...10000回繰り返し]
<body id = top>
<div>...[50回ネスト]<ahref= foo> bla </a> </ div> [...]
[前の行が10000回繰り返されました]
(基本的に、ルートノードと10000から一致する1つのセレクターまでトラバースするためにそれぞれ50のネストされたdivを持つ10000行)
window.onload()
Safari 5では2.2秒、Firefox 3.6.10では10秒弱でロードおよびレンダリング(実行までの時間)します。
クラスセレクターが非適用ルールから削除されると、.foo
ページはSafari 5では約200秒、Firefox3.6.10では96秒かかります。これは、子孫セレクターの実装がいかに悪いかを示しています(この場合、10000の各ルールは、ルールが失敗する#topまでトラバーサルを引き起こす可能性があります)。
チャイルドセレクターはどのように運賃を支払いますか?#foo > span > div > div > div > div > div a {color: red;}
(これも一致することはありませんが、6つの親ノードのトラバーサルを強制します)Safari 5では27秒、Firefox3.6.10では31秒かかります。
結論
子孫セレクターと子セレクターはどちらも、現在主要なブラウザーを嫌っています。速度が気になる場合は、少なくとも非常に一般的なHTMLタグ(a、img、divなど)の場合は、すべてのスタイル付きタグに醜いclass/id属性を追加することをお勧めします。