ホームページ >ウェブフロントエンド >htmlチュートリアル >ブラウザ レンダリングの原理の概要_html/css_WEB-ITnose

ブラウザ レンダリングの原理の概要_html/css_WEB-ITnose

WBOY
WBOYオリジナル
2016-06-24 11:54:03951ブラウズ

このタイトルを見たら、必ずこの魔法の記事「ブラウザの仕組み」を思い出すでしょう。この記事はブラウザの詳細について詳しく説明しており、中国語にも翻訳されています。なぜ私はまだ書きたいのでしょうか?理由は 2 つあります。

1) この記事は長すぎて、一度に読むにはコストがかかりすぎます。

2) この記事を一生懸命読んだ後、多くのことは理解できましたが、私の仕事にはあまり役に立たないようです。

そこで、上記2つの問題を解決するためにこの記事を書いていきます。通勤中やトイレに座りながら読んでいただき、仕事に活かせる内容を学んでいただければ幸いです。

ブラウザのワークフロー

早速、画像を見てみましょう:

上の画像から、いくつかのことがわかります:

1) ブラウザは 3 つのことを解析します:

  • 1実際、Webkit にはこれら 3 種類のドキュメントに対応する 3 つの C++ クラスがあります。これら 3 つのファイルを解析すると、DOM ツリーが生成されます。
  • CSS、CSS を解析すると CSS ルール ツリーが生成されます。
  • Javascript、スクリプトは主に DOM API と CSSOM API を通じて DOM ツリーと CSS ルール ツリーを操作します
  • 2) 解析が完了すると、ブラウザ エンジンは DOM ツリーと CSS ルール ツリーを通じてレンダリング ツリーを構築します。注:

  • レンダリング ツリー Header や display:none などの一部のものをレンダリング ツリーに配置する必要がないため、レンダリング ツリーは DOM ツリーと同等ではありません。
  • CSS のルール ツリーは、主にマッチングを完了し、レンダリング ツリー上の各要素に CSS ルールをアタッチすることです。つまり、DOM ノードです。フレームとも言います。
  • 次に、各フレーム (つまり、各要素) の位置を計算します。これは、レイアウトとリフローのプロセスとも呼ばれます。
  • 3) 最後に、オペレーティング システムのネイティブ GUI の API を呼び出して描画します。

    DOM 解析

    HTML DOM ツリー解析は次のとおりです:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    < html >

    <

    < >

    < ; ボディ >

    < ディビジョン >

    ;

    上記のHTMLは次のように解析されます:

    以下は、SVG タグを使用した別のケースです。次の HTML ドキュメントがあると仮定すると、

    CSS 解析

    CSS 解析はおそらく次のようになります (以下は主に Firefox での Gecko の再生方法について説明します)。次の HTML ドキュメントがあると仮定します。

    4

    5

    6

    8

    >

    < ;

    フランクリン FDR はこう言いました。 恐怖そのものです。"

    DOM ツリーは次のようになります:

    、CSS ドキュメントは次のようになります:

    1

    2

    3

    4

    / * ルール 1 */ doc { 表示: ブロック; 1em; }

    /* ルール 2 */ タイトル { 表示: フォントサイズ: 3em;

    /* ルール 3 */ パラ { : block; }

    /* ルール 4 */ [class="emph"] { font-style: italic; }

    CSS ルール ツリーは次のようになります:

    注、図ルール4 は 2 回表示され、1 回は独立して、もう 1 回はルール 3 の子ノードとして表示されます。したがって、CSS ルール ツリーの確立は DOM ツリーに基づいて行う必要があることがわかります。 CSS マッチング DOM ツリーは主に CSS のセレクターを右から左に解析する方が高速であると多くの人が考えていますが、実際には必ずしもそうではありません。キーは、CSS セレクターの記述方法によって異なります。

    注: HTML 要素の CSS マッチングは、パフォーマンスの問題を伴うかなり複雑な問題です。したがって、DOM ツリーは小さくするべきで、CSS はできる限り ID とクラスを使用し、オーバーレイしないでください...

    これら 2 つのツリーを通じて、次のことがわかります。 1 つはスタイル コンテキスト ツリーと呼ばれるもので、次のとおりです (CSS ルール ノードを DOM ツリーにアタッチします):

    したがって、Firefox は基本的に CSS 解析を通じて CSS ルール ツリーを生成し、DOM コンテキストを比較することによってスタイルを生成します。ツリーを作成し、Firefox がスタイル コンテキスト ツリーをそのレンダー ツリー (フレーム ツリー) に関連付けることでそれを完成させます。注: Render Tree は、いくつかの非表示のノードを削除します。そして、Firefox のいわゆる Frame は DOM ノードです。その名前に混同しないでください

    注: Firefox とは異なり、Webkit はこれを行うために 2 つのツリーを使用します。Webkit には、対応する DOM ノードに Style オブジェクトを直接保存する Style オブジェクトもあります。

    レンダリング

    レンダリングプロセスは基本的に次のとおりです(黄色の4つのステップ):

    1. CSSスタイルを計算する
    2. レンダーツリーを構築する
    3. レイアウトの位置、ラップするかどうか、さまざまな位置、オーバーフロー、z - インデックス属性...
    4. 正式オープン

    注: 上記のプロセスには多くの接続線があるため、JavaScript による DOM 属性または CSS 属性の動的変更によって、一部の変更は再レイアウトされません。 、たとえば、変更された CSS ルールが一致しないなど、空を指す矢印だけです。

    ここで説明する重要な概念が 2 つあります。1 つはリフロー、もう 1 つはリペイントです。これら 2 つは同じものではありません。

  • 再描画?? 特定の CSS の背景色が変更されたなど、画面の一部を再描画する必要があります。ただし、要素の幾何学的寸法は変わりません。
  • リフロー?? コンポーネントの幾何学的サイズが変更されたため、レンダー ツリーを再検証して計算する必要があることを意味します。レンダー ツリーの一部または全体が変更されました。これがリフロー、またはレイアウトです。 (HTMLはフローベースのレイアウト、つまりフローレイアウトを使用するため、コンポーネントの幾何学的なサイズが変更された場合、再レイアウトする必要があります。これはリフローとも呼ばれます) リフローは<のルートフレームから再帰的に開始されます。 html> 下に進むと、リフロー プロセス中に、すべてのノードの幾何学的サイズと位置が順番に計算されます (ラップする必要があるテキスト文字列など)。
  • 以下は、Wikipedia を開いたときのレイアウト/リフローのビデオです (注: HTML は初期化中にリフローも実行します。これは初期リフローと呼ばれます)。それを感じることができます:

    リフローのコストは、リペイント もっともっと。 DOM ツリー内の各ノードにはリフロー メソッドがあり、ノードのリフローは、子ノード、さらには親ノードや兄弟ノードのリフローにつながる可能性があります。 一部の高性能コンピューターでは問題にならない可能性がありますが、携帯電話でリフローが発生すると、このプロセスは非常に面倒で電力を消費します

    したがって、次のアクションは比較的コストがかかる可能性があります。

  • DOM ノードを追加、削除、または変更すると、リフローまたは再ペイントが発生します
  • DOM の位置を移動したり、アニメーションを作成したりすると、
  • CSS スタイルを変更するとき。
  • ウィンドウのサイズを変更するとき(モバイル版にはこの問題はありません)、またはスクロールするとき。
  • Web ページのデフォルトのフォントを変更するとき。
  • 注: display:none はリフローをトリガーしますが、visibility:hidden は位置の変更が見つからないため、再ペイントのみをトリガーします。

    スクロールについてもう少し教えてください。一般的に、スクロール時にページ上のすべてのピクセルがスクロールする場合、パフォーマンスに問題はありません。これは、グラフィック カードがこの種のフルスクリーン ピクセルに適していないためです。下に移動するアルゴリズムは非常に高速です。しかし、背景画像が固定されている場合、または一部の要素がスクロールせず、一部の要素がアニメーション化されている場合、このスクロール操作はブラウザにとって非常に苦痛なプロセスになります。これらのページの多くがスクロール時のパフォーマンスがいかに低いかがわかります。スクロールするとリフローが発生する可能性もあるためです。

    基本的に、リフローには次の理由があります:

  • 初期。 Web ページが初期化されるとき。
  • 増分。 DOM Treeを操作する際の一部のJavaScript。
  • サイズを変更します。一部のコンポーネントの寸法が変更されました。
  • スタイルチェンジ。 CSS プロパティが変更された場合。
  • 汚い。同じフレームのサブツリーでいくつかの増分リフローが発生します。
  • それでは、例を見てみましょう:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    var bstyle = document.body.style; // キャッシュ

    bstyle.padding = "20px" ; // リフロー、再ペイント

    bstyle.border = "10px ソリッドレッド" ; // 再度リフローして再ペイント

    bstyle.color = "blue" ; // 再描画

    bstyle.backgroundColor = "#fad" ; // 再描画

    bstyle.fontSize = "2em" ; //新しい DOM 要素 - リフロー、再描画

    document.body.appendChild(document.createTextNode( 'dude!' )); もちろん、私たちのブラウザは賢いので、上記のようにはなりません。スタイルを変更すると、リフローまたは再ペイントされます。

    一般に、ブラウザはそのような操作のバッチを蓄積してから、非同期リフローまたは増分非同期リフローとも呼ばれるリフローを実行します

    。ただし、ウィンドウのサイズ変更やページのデフォルトのフォントの変更など、場合によってはブラウザがこれを実行しません。これらの操作の場合、ブラウザはすぐにリフローします。

    ただし、場合によっては、スクリプトによってブラウザーがこれを実行できないことがあります。たとえば、次の DOM 値をリクエストした場合です:

    offsetTop, offsetLeft, offsetWidth, offsetHeight scrollTop/Left/Width/Height

    clientTop/ Left IE の /Width/Height getComputedStyle()、または currentStyle

    プログラムがこれらの値を必要とする場合、ブラウザは最新の値を返す必要があり、これにより一部のスタイル変更もフラッシュされるため、頻繁なリフロー/再ペイントが発生します。 。
    1. リフロー/再ペイントを減らす
    2. ベストプラクティスをいくつか示します:
    3. 1) DOM スタイルを 1 つずつ変更しないでください。これを行う代わりに、CSS クラスを事前定義してから DOM の className を変更することをお勧めします。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    // 悪い

    var left = 10,

    top = 10;

    el.style.left = left + "px" ;

    // 良い

    el.className += "theclassname" ;

    // 良い

    el.style.cssText += "; left: " + left + "px; top: " + top + "px;"

    2) DOM をオフラインで変更します。例:

  • documentFragment オブジェクトを使用してメモリ内の DOM を操作します
  • 最初に DOM に display:none (リフローを使用) を指定します。その後、必要に応じて変更できます。たとえば、100 回変更してから再度表示します。
  • DOM ノードをメモリにクローンし、必要に応じて変更します。変更が完了したら、オンラインのノードと交換します。
  • 3) DOM ノードの属性値をループ内の変数としてループ内に置かないでください。 そうしないと、このノードの属性の読み取りと書き込みが大量に行われることになります。

    4)下位レベルの DOM を可能な限り変更します。もちろん、下位レベルの DOM を変更すると、広い範囲のリフローが発生する可能性がありますが、その影響は小さい可能性もあります。

    5)アニメーション化された HTML 要素に固定位置または絶対位置を使用すると、CSS を変更してもリフローしません。

    6)テーブル レイアウトは決して使用しないでください。小さな変更により、テーブル全体が再配置される可能性があるためです。

    このように、最初の行全体が受信されると、ユーザー エージェントはテーブルのレイアウトを開始できます。オーバーフローするコンテンツを含むセルは、「overflow」プロパティを使用して列幅を決定します。オーバーフロー コンテンツをクリップするかどうか。

    固定レイアウト、CSS 2.1 仕様

    このアルゴリズムは、最終的なレイアウトを決定する前にユーザー エージェントがテーブル内のすべてのコンテンツにアクセスする必要があり、複数のパスが必要になる可能性があるため、非効率である可能性があります。 .

    自動レイアウト、CSS 2.1 仕様

    いくつかのツールといくつかの記事

    時々、IE で何を変更したのか分からず、CPU が突然 100 % まで上昇し、その後、再描画/リフローが完了するまでに数秒かかる このようなことは IE の時代によく起こりました。したがって、コード内に不適切なものがないかどうかを確認するのに役立つツールが必要です。

  • Chrome では、Google の SpeedTracer は、ブラウジングのレンダリングにかかる​​コストを確認できる非常に強力なツールです。実際、Safari と Chrome はどちらも開発者ツールでタイムラインを使用できます。
  • Firebug をベースにした Firebug Paint Events という Firefox 用のプラグインも優れています。
  • IE では、dynaTrace と呼ばれる IE 拡張機能を使用できます。
  • 最後に、ブラウザのパフォーマンスを向上させるために次の記事を忘れないでください:

  • Web パフォーマンスのベスト プラクティス
  • Web サイトの読み込みを高速化するための 14 のルール
  • 参考
  • David Baron のスピーチ: Fast CSS: ブラウザーが Web ページをレイアウトする方法: スライドショー、すべてのスライド、オーディオ (MP3)、セッション ページ、Lanyrd ページ

  • ブラウザーの仕組み: http://taligarsiel.com/ Projects/howbrowserswork1 .htm
  • Mozilla のスタイル システムの概要: https://developer.mozilla.org/en-US/docs/Style_System_Overview
  • Mozilla のリフローに関するメモ: http://www-archive.mozilla.org/ newlayout/doc/reflow .html
  • レンダリング: 再ペイント、リフロー/リレイアウト、再スタイル: http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/
  • 効果的なレンダリング CSS: http://css-tricks .com/efficiently- rendering-css/
  • Webkit レンダリングのドキュメント: http://trac.webkit.org/wiki/WebCoreRendering
  • 声明:
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。