HTMLおよびCSSアルゴリズムの計算の複雑さについて

ブラウザにロードされたHTMLドキュメントには、DOM要素のツリーとCSSルールのセットがあります。 各CSSルールはペアです-セレクターとプロパティのリスト。



計算の観点からHTMLドキュメントを描画する価値は何なのか、実際には何だと思いますか? 思想家が考える知識と彼女の内側のネオンは、不透明度によって明るく輝いています。0.5要素では明らかに不十分です。



実際、これがこれらの記事の目的です-HTMLとCSSの表示の計算の複雑さ。 HTML / CSSレンダリングエンジン(HTMLayoutとSciter)の実装に自分の経験を使用していることに注意したいのですが、この領域の計算上の問題は普遍的です-HTMLとCSS仕様の性質によって決定されます。



CSSセレクターについての言葉



パーサーがN要素で構成されるDOMツリーに変わったHTMLドキュメントを想像してください。 このドキュメントのスタイルシステムは、 S CSSルールで構成されています。 次に、すべてのDOM要素のスタイル割り当て手順の計算の複雑さは 、次のように表されます。



O ( N * S * D )





ここで、Dは使用されるツリーとセレクターの「深さ」のメトリックです。



例として、この「素晴らしい」ルールを考えてみましょう。



body * { background:red; }







'*'-赤い背景色を<body>内の各要素に割り当てます。 このようなルールの実際的な利点は、もちろん、少しですが、必要なものを説明することです:DOMのn番目の要素を取得し、bodyタグのすべての親を(深さで)繰り返します。 そして各要素に対して。 このようなルールがSしかない場合、上記の式が得られます。



原則として、N * S * Dは静的なケースではそれほど怖くない-一度計算して忘れてしまった。 しかし、頻繁な動的変更の場合、問題が発生する可能性があります。 たとえば、コンテナ要素のクラスを変更した場合、そのサブツリー全体でスタイルを再カウントする必要があります。 そしてこれも、一般的な場合、 O ( N * S * D )



タスクです。



もちろん、CSS実装はスタイルの再計算のプロセスを最適化しようとしますが、これは常に可能とは限りません。 O(N ...)の問題に対処する主な方法は、結果キャッシュを使用することです。 要素のスタイルを決定するときに、前の要素を確認し、検索された要素と「類似」している場合は、そのスタイル(定義されている場合)を取ることができます。 しかし、このトリックは、たとえばli:nth-child(even)



ようなルールでつまずきます。 私が考える理由は明らかです。



たとえば、WebKitは動的属性セレクターをまったくサポートしていません。 たとえば、特定のDOM属性「mode」の値とbody[mode=first] .widget {color:red}



およびbody[mode=second] .widget {color:green}



の形式のルールのペアを変更してドキュメントの表示モードを切り替える場合(WebKitでは)成功しません。 これがこのエンジンの最適化です。



スタイルを使用するためのベストプラクティス:



  1. ルールの総数に従います。 このドキュメントで何らかのルールが使用されていない場合(セレクターを満たす要素がない場合)、CPUをロードします。 そのようなルールは削除する必要があります。
  2. 複合セレクターでは、右端のセレクターをより具体的(具体的?)にする必要があります。

    例: ul.cls2 li



    セレクターはul li.cls1



    セレクターよりも悪いです。最初のケースでは、すべてのli要素とその親がul.cls2をスキャンし、2番目では、深さ検索がすでに実行されたliのセット-それらのみclass = cls1が与えられているli

  3. .cls2 .cls1



    .cls2 > .cls1



    より「悪い」です。 2番目のケースでは、コンプライアンスチェックは常に要素自体とその親に限定されます。 前者の場合、表示深度は潜在的にルート<html>を含みます。


レイアウトアルゴリズムに関する言葉



...そして、誰かがこのトピックに興味があるなら、これは次の記事のトピックです。



All Articles