34

単一のスタイルシートを持つHTMLページがあるとしましょう<link>。ブラウザはこのスタイルシートのルールをどのように取得してHTMLに適用しますか?私はそれをより速くする方法について尋ねていません、私はレンダリング自体がどのように扱われるか知りたいです。

スタイルシートを解析して結果を段階的にレンダリングするときに、各ルールを1つずつ適用しますか?または、CSSファイルのコンテンツが完全にダウンロードされ、完全に評価されてから、HTMLに一度に適用されますかまたは、他の何か?

レンダリング速度に影響するCSSルールの順序に関する質問に先に回答を投稿した後、スタイルシートがロードさたときにスタイルがレンダリングされることを前提として、これを尋ねます。したがって、最初のルールは最後のルールの前に適用され、一度にすべてではありません。どこでアイデアを思いついたのかわかりませんが、それは私がいつも考えていたものです。

サーバーで次のようなデモを試しました。

<!DOCTYPE html>
<html>
<head>
   <title>Test</title>
   <link rel="stylesheet" href="test.css" />
</head>
<body></body>
</html>

test.cssコンテンツ:

html { background:green }
/* thousands of lines of irrelevant CSS to make the download slow */
html { background:red }

Firefox 5でテストすると、最初は緑になり、次に赤に変わると思っていました。それは起こりませんでした。ルールが競合する2つの別々のスタイルシートを試してみたところ、同じ結果が得られました。多くの組み合わせの後、私がそれを機能させる唯一の方法は、のインライン<style>ブロックであり<head>、競合するルールはから来ています<link><body>リンクタグを除いて本体自体は完全に空でした)。タグにインラインstyle属性を使用し、<html>このスタイルシートをロードしても、期待したちらつきは発生しませんでした。

再描画はCSSの影響を受けますか、それともスタイルシート全体がダウンロードされ、最終出力がどうあるべきかについてルールが計算された後、最終出力が一度に適用されますか?CSSファイルはHTML自体と並行してダウンロードしますか、それとも(スクリプトタグのように)ブロックしますか?これは実際にどのように機能しますか?

私は最適化のヒントを探していません。将来それらを引用できるように、この主題に関する信頼できる参考文献を探しています。関係のない大量の資料を見つけずにこの情報を検索することは非常に困難でした。概要:

  • すべてのCSSコンテンツは、適用される前にダウンロードれますか?(参考にしてください)
  • @importこれは、複数<link>のs、インラインスタイル属性、<style>ヘッド内のブロック、さまざまなレンダリングエンジンなどの影響を受けますか?
  • CSSコンテンツのダウンロードは、HTMLドキュメント自体のダウンロードをブロックしますか?
4

3 に答える 3

16

ブラウザはこのスタイルシートのルールをどのように取得してHTMLに適用しますか?

通常、これはストリーミング方式で行われます。ブラウザはHTMLタグをストリームとして読み取り、これまでに見た要素に可能なルールを適用します。(明らかに、これは単純化です。)

興味深い関連Q&A:CSSセレクターを使用して、ストリーミングパーサー(SAXストリームなど)からHTML要素を収集します (私が考えている記事を検索する際の迂回)。


ああ、ここにあります:親セレクターがない理由

私たちはしばしば、私たちのページを要素とコンテンツでいっぱいのこれらの完全で完全なドキュメントと考えます。ただし、ブラウザはストリームのようにドキュメントを処理するように設計されています。サーバーからドキュメントの受信を開始し、完全にダウンロードされる前にドキュメントをレンダリングできます。各ノードは評価され、受信時にビューポートにレンダリングされます。

サンプルドキュメントの本文を見てください。

<body>
   <div id="content">
      <div class="module intro">
         <p>Lorem Ipsum</p>
      </div>
      <div class="module">
         <p>Lorem Ipsum</p>
         <p>Lorem Ipsum</p>
         <p>Lorem Ipsum <span>Test</span></p>
      </div>
   </div>
</body>

ブラウザは上部から始まり、body要素が表示されます。この時点で、それは空であると考えています。それは他に何も評価していません。ブラウザは、計算されたスタイルが何であるかを判断し、それらを要素に適用します。フォント、色、線の高さは何ですか?これを理解した後、画面にペイントします。

次に、divIDが。の要素が表示されますcontent。繰り返しますが、この時点では、空であると見なされます。それは他に何も評価していません。ブラウザがスタイルを把握してから、divペイントされます。ブラウザは、本体を再描画する必要があるかどうかを判断します。要素は幅が広くなったのか、それとも高くなったのでしょうか。(他にも考慮事項があると思いますが、幅と高さの変更は、子要素が親に与える最も一般的な影響です。)

このプロセスは、ドキュメントの最後に到達するまで続きます。

CSSは右から左に評価されます。

CSSルールが特定の要素に適用されるかどうかを判断するには、ルールの右側から開始し、左側に向かって機能します。

すべての要素に対してそのようなルールがある場合body div#content p { color: #003366; }(ページにレンダリングされるとき)、最初にそれが段落要素であるかどうかを尋ねられます。divそうである場合は、DOMを上に移動し、コンテンツのIDを持つかどうかを確認します。探しているものが見つかると、に到達するまでDOMを上っていきますbody

右から左に操作することにより、ブラウザは、ビューポートにペイントしようとしているこの特定の要素にルールが適用されるかどうかをはるかに速く判断できます。どのルールのパフォーマンスが高いか低いかを判断するには、要素にスタイルを適用できるかどうかを判断するために評価する必要のあるノードの数を把握する必要があります。


では、なぜスタイルシートのコンテンツが段階的に適用されなかったのでしょうか(最初に緑、次に赤)。

答えは、外部スタイルシートはダウンロード時に解析されますが、スタイルシート全体が解析されるまで適用されないということだと思います。確かに、スタイルシートを解析する際に、ブラウザーは不要で冗長なCSSルールを最適化します。

今のところそれを裏付ける証拠はありませんが、その説明は私には合理的に聞こえ、外部スタイルとインラインスタイルの両方であなたが見ているものと一致しています。

于 2011-08-05T03:45:00.003 に答える
9

最初に理解しておくべき最も重要なことは、すべてのCSSがダウンロードされるまで、ブラウザーはページのペイントを開始できないということです。(W3C仕様では、CSSリンクはヘッドでのみ許可されると規定されているため、bodyタグのスタイルシートへのリンクを開始すると、ブラウザーによってこの状況の処理が異なります。)

これで、Webページがストリームとして読み取られ、CSSルールがHTML要素に適用されてページに送られます。以下にリンクされているGoogleの記事を引用するには:

ブラウザがHTMLを解析すると、表示されるすべての要素を表す内部ドキュメントツリーが構築されます。次に、標準のCSSカスケード、継承、および順序付けのルールに従って、要素をさまざまなスタイルシートで指定されたスタイルに一致させます。

だから今あなたの質問に対処するために:

スタイルシートを解析して結果を段階的にレンダリングするときに、各ルールを1つずつ適用しますか?または、CSSファイルのコンテンツが完全にダウンロードされ、完全に評価されてから、HTMLに一度に適用されますか?または、他の何か?

すべてのCSSをダウンロードしてから、ドキュメントをトップダウンでペイントし始めます。

Firefox 5でテストすると、最初は緑になり、次に赤に変わると思っていました。それは起こりませんでした。ルールが競合する2つの別々のスタイルシートを試してみたところ、同じ結果が得られました。

これは、CSSがすべて最初にダウンロードされ、次に要素に遭遇したときに、カスケードがどのように機能するかにより、赤いスタイルのみが適用されたためです。

多くの組み合わせの後、私がそれを機能させる唯一の方法は、のインライン<style>ブロックであり<head>、競合するルール<link><body>

これが発生した理由を正確に言うことはできませんが、ブラウザがbodyタグでCSSを検索せず、ペイントを開始し、body CSSに遭遇してから、再ペイントしたと思います。

再描画はCSSの影響を受けますか?

私は正直に言って、JSによって引き起こされた塗り直しについてもっと心配するでしょう。ただし、DOMが非常に大きい場合は、位置がおかしいためにリフローが発生しないようにCSSを構造化するのが理にかなっています。@Mattは、その問題をカバーするいくつかの優れたリンクを提供しました。いくつかの優れたリソース:

http://www.dayofjs.com/videos/22158462/web-browsers_alex-russel Alex Russellが、WebkitがCSSを解析する方法、リフローとリペイントがどのように機能するか、およびそれらをトリガーする方法について、約36分間詳細に説明します。

http://code.google.com/speed/page-speed/docs/rendering.html これは、CSSレンダリングを最適化する方法に関する基本的な記事です。

于 2011-08-05T04:19:09.717 に答える
1

マークされた答えについてはよくわかりません。私はそれが正しいとは思えません。Google Developersからのこのリンクによると、ブラウザは最初にHTMLファイルをダウンロードし、外部リソースにリンクされたCSSファイルを確認すると、CSSが影響を与えないため、指定されたHTMLファイルのDOM構造を同時に作成しながらCSSファイルのダウンロードを開始します。 DOM。ブラウザがCSSファイルをダウンロードしているときは、ドキュメントにスタイルが適用されないことに注意してください。

CSSファイルをダウンロードした後(スクリプトファイルがないと仮定)、DOMの構築が完了すると、ブラウザーはCSSプロパティのDOMツリー内のノードへのマッピングを開始します。この後、レンダリングツリーと呼ばれる別のツリーが作成され、長方形のボックスとして表示されるすべてのオブジェクトが作成されます。レンダリングツリーが完了した後でのみ、画面へのペイントが開始されます。

要約する:

  • ブラウザはCSSファイルを完全にダウンロードします。
  • ブラウザは、ダウンロード時にページにスタイルを適用しません。ダウンロードが完了すると、ルールのマッピングが開始されます。
  • ルールは、レンダリングツリーの構築段階でのみ適用されます。
  • CSSファイルをダウンロードしても、HTMLのダウンロードはブロックされません。ブラウザに注意する必要があります

最初にすべてのhtmlファイルをダウンロードし、次にスタイルファイルとスクリプトファイルをダウンロードします。

Chromeのデベロッパーコンソールを使用して、これらを確認できます。これらすべてを表示するには、[タイムライン]タブを使用します。

タイムライン画像のサンプルをここに示します。この回答の冒頭に投稿したリンクはすべてを説明しています。

于 2015-06-12T04:12:43.533 に答える