回流 (Reflow) 和重繪 (Repaint) 是什麼?以及如何優化?

回流 (Reflow) 和重繪 (Repaint) 是什麼?以及如何優化?

回流 (Reflow) 是指網頁渲染引擎根據元素的尺寸、位置和顯示屬性來重新計算頁面的排版和布局,是網頁渲染過程中的一個重要步驟。重繪 (Repaint) 是指網頁渲染引擎根據顯示屬性 (如顏色、文字大小等) 重新繪制頁面元素,不影響元素的位置和尺寸。

通過有效控制回流和重繪,可以提高網頁的渲染性能。本篇文章會從瀏覽器渲染過程,討論到回流 (Reflow) 和重繪 (Repaint) 的概念,以及如何優化。

瀏覽器渲染過程瀏覽器在渲染畫面時,會經過幾個過程:

解析 HTML 和樣式計算 (parsing and style calculation) 把 HTML 解析成 DOM,把 CSS 解析成 CSSOM,DOM 和 CSSOM 合併成渲染樹 (render tree)。可參考下圖所示:

DOM and CSSOM 合併成為渲染樹圖片來源:https://web.dev/critical-rendering-path-render-tree-construction/佈局 (Layout)

渲染樹 (render Tree) 有 DOM 的結構和每個節點的樣式,但這還不足以呈現頁面,還需要計算個節點在畫面上的大小和位置,這個過程稱之為佈局 (layout),並且這個過程會產生一個佈局樹 (layout Tree)。

繪製 (paint) 擁有 DOM、樣式和佈局仍然不足以呈現頁面,瀏覽器仍然必須判斷元素的繪製順序。可以把這個過程想像成為繪畫過程的註釋 (paint record),例如:

首先是要畫個背景然後在 (x,y,w,h) 位置上是文字然後再畫個矩形如下圖所示

產生繪製紀錄圖片來源:https://developer.chrome.com/blog/inside-browser-part3/#paint合成 (compositing)

前三個步驟中,瀏覽器已經獲得了渲染頁面所需的資訊,但為了提高整體渲染效率,瀏覽器會再透過合成 (compositing),將資訊渲染到畫面上。合成 (compositing) 是一種將頁面的各個部分分成圖層 (layers) 的技術,而這個技術會在合成線程 (compositor thread) 這個單獨的線程執行。在這個過程完成之後,還會再產生一個圖層樹 (layer tree),最終才會渲染到畫面上。

回流 (Reflow) 和重繪 (Repaint)了解完瀏覽器的渲染過程後,我們回到問題:瀏覽器中的回流 (Reflow) 和重繪 (Repaint) 是什麼 ?以及如何優化?

回流 (Reflow) 和重繪 (Repaint) 指的就是渲染的佈局 (layout) 和繪製 (paint) 的步驟。當我們做了某些事情改變佈局或樣式,就會觸發回流 (Reflow) 或重繪 (Repaint)。

要注意的是,瀏覽器的渲染過程其實是有代價的,因為在渲染過程中,每個步驟都會使用上一個操作的結果來創建新數據。例如:如果佈局樹 (layout Tree) 改變,那就會需要重新繪製。所以如果能夠盡量避免回流 (Reflow) 或重繪 (Repaint),就能夠大大提升效能。

何時發生回流 (Reflow) 和重繪 (Repaint)何時發生回流 (Reflow)?影響瀏覽器效能很重要的關鍵因素,因為可能導致整個或部分頁面的佈局更新,可能因為一個節點大小的改變,就會觸發整的頁面的回流。例如:改變 width、height、font-size 等。

當一個元素的長與寬改變,可能會影響到畫面中其他元素的編排,所以每當有一個元素的佈局改變,瀏覽器的 CPU 需要重新計算整個頁面中不同元素的長寬、間距等。在計算的期間,會沒辦法處理起他任務 (例如使用者在點擊按鈕,可能會要等一陣子才有回應,因為瀏覽器無暇處理)。

這也是為什麼,回流對效能的影響,往往比重繪來得大。

何時發生重繪 (Repaint)?當頁面上的某個元素需要改變顏色或其他不影響布局的屬性時,瀏覽器會對其進行重繪 (repaint)。與回流不同,重繪不會影響頁面布局,但是也會影響頁面的性能。例如:改變 outline、visibility、color、background-color等。

減少回流 (Reflow) 和重繪 (Repaint)在瀏覽器渲染過程中最後一步驟是合成 (compositing),在某些情況,我們可以透過一些技巧只需要讓瀏覽器合成 (compositing),而避免回流 (Reflow) 和重繪 (Repaint)。

以下提供幾個方法:

移動調整元素時,使用 transform使用 opacity 來改變元素的能見度如果需要頻繁重繪或回流的節點,可以透過 will-change 設定成獨立的圖層,因為獨立的圖層可以避免該節點渲染行為影像到其他節點。body > .sidebar {

will-change: transform;

}

避免頻繁用 JavaScript 操作 DOM 節點

相关推荐

手机起名软件排行榜
365网新闻

手机起名软件排行榜

📅 06-27 👁️ 9811
20 exo学院类的橙光游戏有哪些?
中爱365APP

20 exo学院类的橙光游戏有哪些?

📅 07-05 👁️ 7686
胸为什么会大
英国beat365官方登录

胸为什么会大

📅 10-10 👁️ 2330
滴滴专车司机怎么加入
中爱365APP

滴滴专车司机怎么加入

📅 07-01 👁️ 2007
暗黑2怎么取下符文
中爱365APP

暗黑2怎么取下符文

📅 10-11 👁️ 4911
卡地亚最经典10款手镯价格(卡地亚手镯经典款多少钱)
英国beat365官方登录

卡地亚最经典10款手镯价格(卡地亚手镯经典款多少钱)

📅 08-26 👁️ 1976
慎的皮肤特效与手感之选:哪些值得一试的选项
电信拉网线怎么收费
365网新闻

电信拉网线怎么收费

📅 07-26 👁️ 1906
狂野飙车8
中爱365APP

狂野飙车8

📅 10-08 👁️ 2507
《诛仙3》官方网站
365网新闻

《诛仙3》官方网站

📅 08-06 👁️ 2178
寻仙手游
中爱365APP

寻仙手游

📅 10-06 👁️ 3536
世界杯积分榜详细
中爱365APP

世界杯积分榜详细

📅 06-29 👁️ 2598