摘要:完成重排后,瀏覽器會重新繪制受影響的部分到屏幕,該過程稱為重繪。重排必然導致重繪,所以重排更加惡心。使用絕對位置定位頁面上的動畫元素,將其脫離文檔流,可以有效的防止重排。
render樹的構建
瀏覽器取回代碼后,首先會構造DOM樹,根據HTML標簽,構造DOM樹。
之后會解析CSS樣式,解析的順序是瀏覽器的樣式 -> 用戶自定義的樣式 -> 頁面的link標簽等引進來的樣式 -> 寫在style標簽里面的內聯樣式
最后根據DOM樹以及解析的CSS樣式,構造RENDER樹,在RENDER樹中,會把DOM樹中沒有的元素給去除,比如head標簽以及里面的內容,以及display:none的元素也會被去除。
一旦RENDER樹構建完成,瀏覽器會把樹里面的內容繪制在屏幕上。
Beautiful page Once upon a time there was a looong paragraph...
...
構造的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 ...重繪(repaint)和重排(reflow)
當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)
因此,盡量不要在修改樣式或者布局信息時查詢樣式,因為查詢的時候會強制重排,導致瀏覽器無法優化多次重排。
使用絕對位置定位頁面上的動畫元素,將其脫離文檔流,可以有效的防止重排。比如有時候做動畫特效時,我們通過設置position:absolute可以有效的減少重排。這讓我想到,以前做動畫的時候通過修改margin-left屬性而不是left屬性絕對是一個很不好的做法。
transform是否可以避免重排重繪問題那么使用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...
http://www.phpied.com/renderi...
http://www.cnblogs.com/zichi/...
寫完文章后又重新查了一下關于CSS3動畫性能方面的文章,發現大漠老師寫的這篇很不錯,而且跟自己理解的觀點有部分相似,先放上來,之后再認真看。
https://www.w3cplus.com/anima...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/50547.html
摘要:完成重排后,瀏覽器會重新繪制受影響的部分到屏幕,該過程稱為重繪。重排必然導致重繪,所以重排更加惡心。使用絕對位置定位頁面上的動畫元素,將其脫離文檔流,可以有效的防止重排。 render樹的構建 showImg(https://segmentfault.com/img/remote/1460000006908155?w=630&h=292); 瀏覽器取回代碼后,首先會構造DOM樹,根據H...
摘要:完成重排后,瀏覽器會重新繪制受影響的部分到屏幕,該過程稱為重繪。重排必然導致重繪,所以重排更加惡心。使用絕對位置定位頁面上的動畫元素,將其脫離文檔流,可以有效的防止重排。 render樹的構建 showImg(https://segmentfault.com/img/remote/1460000006908155?w=630&h=292); 瀏覽器取回代碼后,首先會構造DOM樹,根據H...
摘要:就如上面的概念一樣,單單改變元素的外觀,肯定不會引起網頁重新生成布局,但當瀏覽器完成重排之后,將會重新繪制受到此次重排影響的部分。因為隊列中,可能會有影響到這些值的操作,為了給我們最精確的值,瀏覽器會立即重排重繪。 showImg(http://ww1.sinaimg.cn/large/005Y4rCogy1fya3fh2jm3j30ku0dwtb2.jpg); 很多人都知道要減少瀏覽...
摘要:對于復雜動畫效果使用絕對定位讓其脫離文檔流對于復雜動畫效果,由于會經常的引起回流重繪,因此,我們可以使用絕對定位,讓它脫離文檔流。硬件加速加速比起考慮如何減少回流重繪,我們更期望的是,根本不要回流重繪。 回流和重繪可以說是每一個web開發者都經常聽到的兩個詞語,我也不例外,可是我之前一直不是很清楚這兩步具體做了什么事情。最近由于部門內部要做分享,所以對其進行了一些研究,看了一些博客和書...
閱讀 917·2021-10-18 13:32
閱讀 3512·2021-09-30 09:47
閱讀 2155·2021-09-23 11:21
閱讀 1878·2021-09-09 09:34
閱讀 3479·2019-08-30 15:43
閱讀 1522·2019-08-30 11:07
閱讀 1061·2019-08-29 16:14
閱讀 724·2019-08-29 11:06