ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptでのRepaintとReflowの使い方を詳しく解説_基礎知識

JavaScriptでのRepaintとReflowの使い方を詳しく解説_基礎知識

WBOY
WBOYオリジナル
2016-05-16 15:48:521003ブラウズ

上級者やフロントエンドの上級者から、CSS ワイルドカード * は使用できない、CSS セレクターのスタックは 3 レベルを超えてはいけない、CSS ではクラス セレクターをできるだけ使用する、HTML を記述するときにテーブルの使用を減らす、などのことをよく聞いたことがありますか?構造はできるだけ単純である必要があります - DOM ツリー これらのアドバイスを待っていますが、ワイルドカードを使用したり、CSS セレクターのレベルが多すぎるとパフォーマンスが低下する可能性があることは大体わかっていました。なぜテーブル タグを使用しないのかについては、私はいつも混乱していました。それで私はそれに従っただけですが、RepainとReflowを知ってから、これらは実際には使いすぎることができないことがわかりました。わかりました、この記事がお役に立てば幸いです!

1. リペイント/リフローとは何ですか?

それでは、まず写真を撮りましょう: ブラウザー解析の一般的なワークフロー

2015727180703820.png (600×196)

この図は理解しやすく、4 つのステップに要約できます:

1. HTML を解析して DOM ツリーを構築する: レンダリング エンジンは HTML ドキュメントの解析を開始し、ツリー内の html タグまたは js によって生成されたタグをコンテンツ ツリーと呼ばれる DOM ノードに変換します。
2. レンダリング ツリーを構築します。CSS (外部 CSS ファイルとスタイル要素、js によって生成されたスタイルを含む) を解析し、CSS セレクターに基づいてノードのスタイルを計算し、別のツリー (レンダリング ツリー) を作成します。
3. レイアウト レンダリング ツリー: ルート ノードから再帰的に呼び出され、各要素のサイズ、位置などを計算し、各ノードに画面上で表示される正確な座標を与えます。
4. レンダリング ツリーを描画します。レンダリング ツリーをトラバースすると、UI バックエンド レイヤーを使用して各ノードが描画されます。

わかりました。Repain と Reflow がそれぞれ 3 番目と 4 番目のステップに表示されていることがわかります。したがって、次の定義を与えます:

DOM 構造内の各要素には独自のボックス (モデル) があり、ブラウザーがさまざまなスタイル (ブラウザー、開発者定義など) に従って計算し、計算結果に従ってその中に要素を配置する必要があります。このプロセスはこれはリフローと呼ばれます。さまざまなボックスの位置、サイズ、その他の属性 (色、フォント サイズなど) が決定されると、ブラウザーはそれぞれの特性に従ってこれらの要素を描画し、ページのコンテンツが表示されます。この処理をリペイントといいます。
これら 2 つのことはブラウザがページをレンダリングするのに非常に重要であり、パフォーマンスに影響を与えることがわかります。したがって、再描画とリフローを引き起こすいくつかの一般的な操作を理解する必要があり、これらを最小限に抑える必要があります。レンダリング速度。

2. リペイントとリフローを引き起こす一部の操作

リフローのコストはリペイントのコストよりもはるかに高くなります。 DOM ツリー内の各ノードにはリフロー メソッドがあり、ノードのリフローは、子ノード、さらには親ノードや兄弟ノードのリフローにつながる可能性があります。一部の高性能コンピュータでは問題ないかもしれませんが、携帯電話でリフローが発生すると、プロセスは非常に困難で電力を消費します。
したがって、次のアクションは比較的コストがかかる可能性があります。

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

注: display:none はリフローをトリガーしますが、visibility:hidden は位置の変更が見つからないため、再ペイントのみをトリガーします。
3. 最適化する方法は?

リフローは避けられず、リフローによるパフォーマンスへの影響は最小限に抑えることができます。

DOM スタイルを 1 つずつ変更しないでください。これを行う代わりに、CSS クラスを事前定義してから DOM className を変更することをお勧めします:

 // 不好的写法
  var left = 10,
  top = 10;
  el.style.left = left + "px";
  el.style.top = top + "px";
  // 推荐写法
  el.className += " theclassname";

DOM をオフラインにしてから変更します。例:
a> documentFragment オブジェクトを使用してメモリ内の DOM を操作します。
b> まず DOM に display:none (1 回再描画) を指定し、その後、必要に応じて変更できます。たとえば、100 回変更してから再度表示します。
c> DOM ノードをメモリに複製し、変更が完了したら、オンラインのノードと交換します。

DOM ノードの属性値をループ内の変数としてループ内に置かないでください。そうしないと、ノードの属性の読み取りと書き込みが大量に行われることになります。

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

アニメーション化された HTML 要素に固定位置または絶対位置を使用する場合、CSS を変更するとリフローが大幅に減少します。

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

これらを理解した後、ブラウザの原理にもっと興味がありますか? OK、ブラウザの原則に関する記事は後ほど更新します。または、最初に他の記事を検索してください。ブラウザの原則を理解することは非常に重要であり、パフォーマンスの高い Web サイトを作成するのに役立ちます。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。