瀏覽器取回代碼後,首先會構造DOM樹,根據HTML標籤,構造DOM樹。php
以後會解析CSS樣式,解析的順序是瀏覽器的樣式
-> 用戶自定義的樣式
-> 頁面的link標籤等引進來的樣式
-> 寫在style標籤裏面的內聯樣式
html
最後根據DOM樹以及解析的CSS樣式,構造RENDER樹,在RENDER樹中,會把DOM樹中沒有的元素給去除,好比head標籤以及裏面的內容,以及display:none
的元素也會被去除。html5
一旦RENDER樹構建完成,瀏覽器會把樹裏面的內容繪製在屏幕上。node
<html> <head> <title>Beautiful page</title> </head> <body> <p> Once upon a time there was a looong paragraph... </p> <div style="display: none"> Secret message </div> <div><img src="..." /></div> ... </body> </html>
構造的DOM樹以下瀏覽器
documentElement (html) head title body p [text node] div [text node] div img ...
RENDER樹以下佈局
root (RenderView) body p line 1 line 2 line 3 ... div img ...
當DOM的變化影響了元素的幾何屬性(寬或高),瀏覽器須要從新計算元素的幾何屬性,一樣其餘元素的幾何屬性和位置也會所以受到影響。瀏覽器會使渲染樹中受到影響的部分失效,並從新構造渲染樹。這個過程稱爲重排。完成重排後,瀏覽器會從新繪製受影響的部分到屏幕,該過程稱爲重繪。並非全部的DOM變化都會影響幾何屬性,好比改變一個元素的背景色並不會影響元素的寬和高,這種狀況下只會發生重繪。性能
重排必然致使重繪,因此重排更加噁心。其實咱們一直研究的應該是怎麼避免觸發屢次重排。優化
添加或者刪除可見的DOM元素 元素位置改變 元素尺寸改變 元素內容改變(例如:一個文本被另外一個不一樣尺寸的圖片替代) 頁面渲染初始化(這個沒法避免) 瀏覽器窗口尺寸改變
var ele = document.getElementById('myDiv'); ele.style.borderLeft = '1px'; ele.style.borderRight = '2px'; ele.style.padding = '5px';
乍一想,元素的樣式改變了三次,每次改變都會引發重排和重繪,因此總共有三次重排重繪過程,可是瀏覽器並不會這麼笨,它會把三次修改「保存」起來(大多數瀏覽器經過隊列化修改並批量執行來優化重排過程),一次完成!可是,有些時候你可能會(常常是不知不覺)強制刷新隊列並要求計劃任務當即執行。獲取佈局信息的操做會致使隊列刷新,好比:動畫
offsetTop, offsetLeft, offsetWidth, offsetHeight scrollTop, scrollLeft, scrollWidth, scrollHeight clientTop, clientLeft, clientWidth, clientHeight getComputedStyle() (currentStyle in IE)
所以,儘可能不要在修改樣式或者佈局信息時查詢樣式,由於查詢的時候會強制重排,致使瀏覽器沒法優化屢次重排。spa
使用絕對位置定位頁面上的動畫元素,將其脫離文檔流,能夠有效的防止重排。好比有時候作動畫特效時,咱們經過設置position:absolute
能夠有效的減小重排。這讓我想到,之前作動畫的時候經過修改margin-left
屬性而不是left
屬性絕對是一個很很差的作法。
那麼使用CSS3的transform
來實現動畫是否能夠避免重排問題?或者說瀏覽器針對這一部分作了其餘優化?
通過一番查找,答案以下:
CSS的最終表現分爲如下四步:Recalculate Style
-> Layout
-> Paint Setup and Paint
-> Composite Layers
按照中文的意思大體是 查找並計算樣式 -> 排布 -> 繪製 -> 組合層
這上面的幾個步驟有點相似於上文說到的重排一定致使重繪,而查詢屬性會強制發生重排。因此上文提到的重排重繪內容能夠結合這裏進行理解。
因爲transform
是位於Composite Layers
層,而width
、left
、margin
等則是位於Layout
層,在Layout
層發生的改變一定致使Paint Setup and Paint
-> Composite Layers
,因此相對而言使用transform
實現的動畫效果確定比left
這些更加流暢。
並且就算拋開這一角度,在另外一方面瀏覽器也會針對transform
等開啓GPU加速。
參考文章
https://www.html5rocks.com/en...
寫完文章後又從新查了一下關於CSS3動畫性能方面的文章,發現大漠老師寫的這篇很不錯,並且跟本身理解的觀點有部分類似,先放上來,以後再認真看。