首頁  >  文章  >  web前端  >  Javascript 中的回流與重繪

Javascript 中的回流與重繪

Susan Sarandon
Susan Sarandon原創
2024-10-18 22:42:02434瀏覽

優化 CSS 以減少不必要的回流和重繪的最佳實踐是什麼,特別是在大型應用程式中?

1. Reflow(版面重新計算):

當瀏覽器重新計算頁面上元素的位置、大小和佈局時,會發生重排(也稱為佈局重新佈局) 。每當頁面佈局發生變化時,例如新增、刪除、調整大小或其可見性發生變化時,都會發生此過程。這是一個比較複雜又耗時的操作

例 :

<div id="box" style="width: 100px; height: 100px; background-color: blue;"></div>

<script>
const box = document.getElementById('box');
// Triggering a reflow by changing width and height
box.style.width = '200px';
box.style.height = '200px';

// Triggering a repaint by changing the background color
box.style.backgroundColor = 'red';
</script>

什麼時候發生回流?

  • 新增、移除或修改 DOM 元素(例如,appendChild、removeChild)。
  • 透過調整寬度、高度、邊距、填滿等 CSS 樣式來變更版面配置
  • 調整視窗大小或更改元素大小。
  • 更改字體大小或字體屬性。
  • 使用 offsetWidth、offsetHeight、scrollTop、getBoundingClientRect() 等方法,因為它們會強制瀏覽器重新計算佈局。

回流焊的工作原理:

當您變更影響頁面佈局的內容時,瀏覽器必須:

  1. 重新計算受更改影響的所有元素的位置和尺寸
  2. 重建佈局樹,它是元素如何佈局的內部表示。

如果許多元素受到一次變更的影響,則回流的成本可能會很高,並且會降低網站的效能。

Reflows and Repaints in Javascript

2.重新繪製(視覺更新)

當元素的視覺屬性改變但版面不變時,會發生 repaint (或 redraw)。它比回流更便宜,因為它只需要更新元素的外觀,而無需重新計算其位置或佈局。重新繪製佈局後(在需要兩者的情況下)或變更不影響佈局的屬性(例如顏色或可見性)時發生。

例 :

<div id="box" style="width: 100px; height: 100px; background-color: blue;"></div>

<script>
// Triggering a repaint by changing the background color
box.style.backgroundColor = 'red';
</script>

什麼時候進行重繪?

  • 變更背景顏色、邊框顏色或可見性屬性。
  • 更改元素的框陰影、輪廓或顏色。
  • 更新不透明度(opacity)、變換(transform)或 z-index。

重繪不涉及重新計算佈局,因此比回流更快,但仍需要重繪頁面的部分內容,這需要一些時間。

渲染管線

  1. DOM 建構:瀏覽器解析 HTML 來建構 DOM(文件物件模型)樹。
  2. CSSOM 建構:解析 CSS 以建立 CSSOM(CSS 物件模型)樹。
  3. 渲染樹建構:將 DOM 和 CSSOM 組合起來建立渲染樹,其中包含每個可見元素的視覺資訊。
  4. 佈局(回流):瀏覽器計算渲染樹中每個可見元素的位置和大小。
  5. 繪製:瀏覽器根據顏色、邊框、陰影等視覺屬性填入像素
  6. 複合:瀏覽器組合不同的繪製層(對於動畫、3D 變換等複雜元素)並將其顯示在螢幕上。

性能影響

  • 回流:在效能方面代價高昂,特別是當它影響頁面的大部分或重複觸發時(例如,在循環中或調整大小時)。它會影響頁面的佈局,需要重新計算元素的位置和大小。
  • 重新繪製:比回流便宜,但仍會影響效能,特別是在許多元素需要頻繁重新繪製的情況下。

如何優化回流和重繪

  1. 最小化DOM 操作 :使用批量DOM 更新(如前所述)或DocumentFragment 等技術一次進行多項更改,而不是一一。

  2. 避免佈局抖動:如果您讀取佈局屬性(例如,offsetHeight)並立即在同一週期內寫入(更改佈局),則會強制回流,稱為佈局抖動。為了避免這種情況,請在不同的步驟中分開讀取和寫入 DOM 屬性。

    <div id="box" style="width: 100px; height: 100px; background-color: blue;"></div>
    
    <script>
    const box = document.getElementById('box');
    // Triggering a reflow by changing width and height
    box.style.width = '200px';
    box.style.height = '200px';
    
    // Triggering a repaint by changing the background color
    box.style.backgroundColor = 'red';
    </script>
    
  3. 使用 CSS 類別 :不要修改單一樣式,而是使用 CSS 類別進行變更。瀏覽器更有效地處理類別切換。

    <div id="box" style="width: 100px; height: 100px; background-color: blue;"></div>
    
    <script>
    // Triggering a repaint by changing the background color
    box.style.backgroundColor = 'red';
    </script>
    
  4. 降低 CSS 的複雜性:避免深層嵌套的元素和過於複雜的 CSS 規則,從而觸發回流。

  5. 當您只想隱藏元素而不影響佈局時,請使用visibility:hidden而不是display:none。 display: none 會觸發重排,而visibility: hide 只會觸發重繪。

結論

  • 回流涉及重新計算頁面佈局,並且在效能方面成本更高。
  • 重新繪製更新視覺外觀而不影響佈局,且成本更低。
  • 最大限度地減少這兩者有助於保持網站的響應速度和速度,從而改善用戶體驗。

以上是Javascript 中的回流與重繪的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn