在認識重繪和回流之前,我們先認識一下一個頁面加載的時候,會發生什麼?
頁面加載時,生成一個DOM樹,DOM Tree裡包含了構成頁面所有的标簽。Style Sheets(CSS樣式表)會生成一個Style Rules。當DOM Tree和Style Rules一起建構出了Render Tree,對于Render Tree的了解:Render Tree和DOM Tree類似,但是Render Tree能夠識别樣式,在Render Tree上,每一個node(節點)都有自己的Style(樣式),但隐藏的節點或是不會用于顯示的部分不會包含在Render Tree上。

上圖是一個頁面在浏覽器中渲染(Webkit)的過程。其中的Layout就是布局,頁面第一次被加載時或是當Render Tree改變需要重新布局時,就産生了回流(reflow)/重排(relayout)。當Render Tree中的一部分(或全部)的node(節點)因為元素的規模尺寸、布局方式、顯示隐藏等改變,浏覽器為了重新渲染部分或整個頁面,重新計算頁面元素位置和幾何結構的過程,也就是重新構造渲染樹 ,這個過程叫做回流(reflow)/重排(relayout)。每個頁面至少發生一次回流/重排,就是頁面第一次被加載時。當頁面中的元素隻是外觀或風格被改變不影響布局,比如更換背景色background-color,這個過程就是重繪。
回流/重排(Reflow):當渲染樹的一部分必須更新并且節點的尺寸發生了變化,浏覽器會使渲染樹中受到影響的部分失效,并重新構造渲染樹。
重繪(Repaint):是在一個元素的外觀被改變所觸發的浏覽器行為,浏覽器會根據元素的新屬性重新繪制,使元素呈現新的外觀。比如改變某個元素的背景色、文字顔色、邊框顔色等等
影響回流(reflow)/重排(relayout)的因素 | 影響重繪(replaint)的因素 |
---|---|
元素的布局和幾何屬性改變時就會觸發reflow。1.頁面初始渲染;2.添加/删除可見DOM元素;3.改變元素位置 ----- 定位屬性及浮動(position,float);4.改變元素尺寸(寬、高、内外邊距、邊框等) ----- 盒子模型相關屬性(height ,padding ,margin , display ,border-width ,min-height);5.改變元素内容(文本或圖檔等)(text-align , line-height ,vertival-align ,overflow , font-size,font-family,font-weight);6.改變視窗尺寸;7.擷取元素的offsetWidth、offsetHeight、clientWidth、clientHeight、width、height、scrollTop、scrollHeight,請求了getComputedStyle(), 或者 IE的 currentStyle | 頁面中的元素更新外觀或風格相關的屬性時就會觸發重繪,如:background,color,visibility, border-style ,border-radius outline-color,cursor,text-decoration, box-shadow |
重繪不一定需要重排(比如顔色的改變),重排必然導緻重繪(比如改變網頁位置)。
優化:
重繪和重排對我們的浏覽器性能有一定的個影響,浏覽器會維護1個隊列,把所有會引起重排,重繪的操作放入這個隊列,等隊列中的操作到一定數量或者到了一定時間間隔,浏覽器就會flush隊列,進行一批處理,這樣多次重排,重繪變成一次重排重繪
減少 reflow/repaint:
(1)不要一條一條地修改 DOM 的樣式。可以先定義好 css 的 class,然後修改 DOM 的 className。
(2)不要把 DOM 結點的屬性值放在一個循環裡當成循環裡的變量。
(3)為動畫的 HTML 元件使用 fixed 或 absoult 的 position,那麼修改他們的 CSS 是不會 reflow 的。
(4)千萬不要使用 table 布局。因為可能很小的一個小改動會造成整個 table 的重新布局。(table及其内部元素除外,它可能需要多次計算才能确定好其在渲染樹中節點的屬性,通常要花3倍于同等元素的時間。這也是為什麼我們要避免使用table做布局的一個原因。)
(5)不要在布局資訊改變的時候做查詢(會導緻渲染隊列強制重新整理)
本文參與 騰訊雲自媒體分享計劃 ,歡迎熱愛寫作的你一起參與!
本文分享自作者個人站點/部落格
https://blog.csdn.net/liuyifeng0000
複制
如有侵權,請聯系 [email protected] 删除。