document.Documentfragment
ドキュメント フラグメントを作成する役割を簡単に紹介します。このフラグメントは実際のDOM
ノードではなくメモリ内に存在するため、その子要素を挿入してもページのリフロー/再描画がトリガーされないため、これを使用して複数のdom
ノードを連続的に作成できます。
1.ケース
ノードを作成する以前の方法
let ul = document.getElementsByTagName('ul')[0]
for (let i = 0; i < 100; i++) {
let el = document.createElement('li')
el.innerHTML = i
ul.appendChild(el)
}
布局(Layout)
ノードが作成されるたびにメインスレッドのリフロー操作がトリガーされ、その後重绘(Piant)
操作が 100 回トリガーされるため、そのパフォーマンス曲線を確認できます。
この方法でフラグメントを作成すると、リフロー操作のみがトリガーされます。
let ul = document.getElementsByTagName('ul')[0]
let frag = document.createDocumentFragment()
for (let i = 0; i < 100; i++) {
let el = document.createElement('li')
el.innerHTML = i
frag.appendChild(el)
}
ul.appendChild(frag)
パフォーマンス分析:
Rendering
比較すると紫色の部分がリフロー操作であることが分かり、フラグメント作成時間の方が有利であることが分かります。
2. 展開する
レンダリング効率を最適化するいくつかの方法を拡張します。
- 1.ブロックを防ぐため、スタイル ファイルは
head
タグ内に配置し、スクリプト ファイルは末尾の前に配置する必要があります。body
- 2.
script
スクリプトはメインのレンダリング スレッドをブロックするため、レンダリングを同期的に実行する必要がない場合は、レンダリングの完了後にロードできます。これを使用して、スクリプトのロード タイミングを制御しますdefer
。 - 3. セレクターを簡素化して最適化し
CSS
、ネストレベルを最小限に抑えます。 - 4.
DOM
複数の読み取り操作 (または複数の書き込み操作) は、一緒に配置する必要があります。2 つの読み取り操作の間に書き込み操作を追加しないでください。 - 5. スタイルを 1 つずつ変更するのではなく、変更
class
または属性によってcsstext
一度にスタイルを変更します。 - 6. この操作はマージ スレッドで行われ、メインのレンダリング スレッドには影響を与えないため、
transform
これを変形と移動に使用してみます。画(Draw)
DOM
7. 要素のスタイルを変更するには、実際の Web ページではなくオフラインを使用してみてくださいDOM
。たとえば、Document Fragment
オブジェクトを操作し、完了後にこのオブジェクトを追加します。DOM
- 8. まず要素を に設定し
display: none
(1 回のリフローと再描画が必要)、次にこのノードで 100 回の操作を実行し、最後に表示を復元します (1 回のリフローと再描画が必要)。こうすることで、100 回の再レンダリングが可能になるのではなく、2 回の再レンダリングが行われることになります。 - 9.または の
position
属性を持つ要素の場合、他の要素への影響を考慮する必要がないため、リフローのオーバーヘッドは比較的小さくなります。absolute
fixed
display
10.不可視要素はリフローや再描画に影響しないため、必要な場合にのみ要素の属性を可視に設定します。さらに、visibility: hidden
これらの要素は再描画にのみ影響し、リフローには影響しません。- 11. 一部の
js
ページ リフロー操作はwindow.requestAnimationFrame()
フレーム アニメーションで実行できます。
!!!述べる:
**reflow
リフロー中に要素の位置/サイズやその他の情報を変更すると、非同期の統合マージ更新がトリガーされるため、最初に変更してから、まだ更新されていないため、前のものをwidth
取得する場合があります**offsetWidth/clientWidth