Rendering: repaint, reflow/relayout, restyle的学习笔记
http://www.zhuoqun.net/html/y2009/1430.html
?
Rendering tree是DOM tree的可見部分
?
?
?
?
頁面渲染的過程:
1. 解析HTML代碼并生成一個 DOM 樹。
2. 解析CSS文件,順序為:瀏覽器默認樣式->自定義樣式->頁面內 的樣式</p> <p>3. </p>
3. 生成一個渲染樹(render tree)。這個渲染樹和DOM樹的不同之處在于,它是受樣式影響的。它不包括那些不可見的節點。
4. 當渲染樹生成之后,瀏覽器就會在屏幕上“畫”出所有渲染樹中的節點。
那什么是 reflow 呢?reflow 是指渲染樹中的一些節點被重新驗證或者大小被重新計算。一個頁面至少會在初始化的時候 reflow 一次。而 repaint 是指屏幕中的一些顯示需要更新,比如更改了某個元素的背景顏色。
reflow 和 repaint 都是需要計算的,會消耗資源,影響用戶體驗。所有對用來生成渲染樹的信息的改動都會觸發 reflow 或者 repaint 。比如:添加或刪除一個DOM節點、把一個節點的display設為none 等。由于reflow 和 repaint 會消耗資源,所以瀏覽器一般都會對此進行優化。有些瀏覽器會建立一個隊列,把發生的 reflow 和 repaint 放進去,然后進行批處理。但是當你獲取某些節點的樣式信息的時候,會破壞瀏覽器的這種默認優化,強迫瀏覽器執行當前所有的 reflow 和 repaint。比如當你獲取某個節點的 offsetTop 的時候,瀏覽器必須提供給你最新的數值,所以就需要把之前的 reflow 和 repaint 都執行。
為了節省資源提高用戶體驗,我們在編寫代碼的時候就必須要注意不能讓瀏覽器 reflow 和 repaint 太頻繁,盡量避免這樣的代碼:
| 1 2 3 | for(i=0;i<n;i++){ el.style.left = el.offsetLeft + 10 + "px"; } |
下面提供一些減少 reflow 和 repaint 的思路:
1. 不要一個一個地去直接修改元素的樣式,最好去修改樣式表,然后修改元素的className。
| 1 2 3 4 5 6 7 8 9 | var left = 10,top = 10; el.style.left = left + "px"; el.style.top = top + "px";// 這樣不好el.className += " theclassname"; // 這樣很好 |
2.批量處理DOM操作,最好不要在當前的DOM樹中直接操作。比如:使用documentFragment 來暫存一些操作;先將要進行操作的DOM節點clone,更改完畢之后再去替換當前的節點;先將要操作的DOM節點的display設置為hidden,執行操作之后再更改回來。
3. 避免一直計算元素樣式。比如在循環中,你可以先用本地變量將計算的樣式保存。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // 不要這么做 for(big; loop; here) {el.style.left = el.offsetLeft + 10 + "px";el.style.top = el.offsetTop + 10 + "px"; }// 最好先存儲到變量里。 var left = el.offsetLeft,top = el.offsetTopesty = el.style; for(big; loop; here) {left += 10;top += 10;esty.left = left + "px";esty.top = top + "px"; } |
總結
以上是生活随笔為你收集整理的Rendering: repaint, reflow/relayout, restyle的学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WebCore中的渲染机制(二):块和内
- 下一篇: Web架构