CSS 処理の詳細、特にRTL マッチングとセレクターの効率を考えると、レンダリング エンジンのパフォーマンスの観点から純粋にセレクターをどのように記述する必要がありますか?
これは、一般的な側面をカバーし、疑似クラス、疑似要素、および関係セレクターの使用または回避を含む必要があります。
N
実行時に、HTML ドキュメントは、平均的な深さの要素を含む DOM ツリーに解析されますD
。適用されるスタイルシートには合計のS
CSS ルールもあります。
要素のスタイルは個別に適用されます。つまり、全体的な複雑さとの間に直接的な関係がN
あります。これは、参照キャッシュや同一要素からのスタイルのリサイクルなどのブラウザー ロジックによって多少相殺される可能性があることに注意してください。たとえば、次のリスト項目には、同じ CSS プロパティ:nth-child
が適用されます (適用されるような疑似クラスがないことを前提としています)。
<ul class="sample">
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
セレクターは、個々のルールの適格性のために右から左に一致します。つまり、最も右のキーが特定の要素に一致しない場合、セレクターをさらに処理する必要はなく、破棄されます。これは、最も右のキーができるだけ少ない要素と一致する必要があることを意味します。以下では、記述子は、ターゲット コンテナーの外側p
の段落を含む、より多くの要素に一致します(もちろん、ルールは適用されませんが、その特定のセレクターの適格性チェックがさらに繰り返されます)。
.custom-container p {}
.container .custom-paragraph {}
リレーションシップ セレクター:子孫セレクターでは、最大でD
要素を反復処理する必要があります。たとえば.container .content
、要素が親子関係にある場合、正常に一致するために必要な手順は 1 つだけですが、DOM ツリーはhtml
、要素の不一致が確認され、ルールが安全に破棄される前に、完全にトラバースする必要があります。これは、チェーンされた子孫セレクターにも適用されますが、いくつかの許容範囲があります。
一方、>
子セレクター、+
隣接セレクター、または:first-child
引き続き追加の要素を評価する必要がありますが、暗黙の深さは 1 であり、それ以上のツリー トラバーサルは必要ありません。
やなどの擬似要素の動作定義は、それらが RTL パラダイムの一部ではないことを意味します。仮定の論理は、ルールが要素のコンテンツの前または後に挿入するように指示するまで、疑似要素自体は存在しないということです (これには追加の DOM 操作が必要ですが、セレクター自体を一致させるために必要な追加の計算はありません)。:before
:after
:nth-child()
またはなどの疑似クラスに関する情報は見つかりませんでし:disabled
た。要素の状態を検証するには、追加の計算が必要になりますが、ルール解析の観点からは、それらを RTL 処理から除外することだけが理にかなっています。
O(N*D*S)
これらの関係を考えると、主に CSS セレクターの深さを最小限に抑え、上記のポイント 2 に対処することによって、計算の複雑さを軽減する必要があります。これにより、CSS ルールまたは HTML 要素の数を最小限に抑えるだけの場合と比較して、定量的に強力な改善が得られます^
浅い、できれば 1 レベルの特定のセレクターは、より高速に処理されます。これは、Google によってまったく新しいレベルに引き上げられました (手動ではなく、プログラムによって!)。たとえば、3 キー セレクターはほとんどなく、検索結果のほとんどのルールは次のようになります。
#gb {}
#gbz, #gbg {}
#gbz {}
#gbg {}
#gbs {}
.gbto #gbs {}
#gbx3, #gbx4 {}
#gbx3 {}
#gbx4 {}
/*...*/
^ - これはレンダリング エンジンのパフォーマンスの観点から言えば真実ですが、トラフィック オーバーヘッドや DOM 解析などの追加要因が常に存在します。