什麼是重繪和重排
重繪就是重新繪製(repaint)
重排就是重新排列(reflow)
DOM發生改變的時候觸發重排,使DOM重新排列,重繪不一定會重排,但是重排一定發生重繪,重繪和重排都會耗費瀏覽器的性能,儘量避免
網頁如何生成
- 解析html繪製DOM樹
- 解析css繪製CSS樹
- 生成render tree(渲染樹)
- flow排列,將渲染樹節點合成(渲染)
- paint繪製,將排列繪製在屏幕上(渲染)
引起重排屬性和方法
改變元素幾何信息(大小和位置),都會引起
- DOM改變
- input 輸入內容改變
- resize
- style屬性改變
- margin
- 計算offsetWidth和offsetHeight
-
局部重排(在一個固定寬高的div裏面)
-
全局重排(在根節點上開始改變)
重繪
發生外觀的變化,沒有改變佈局
優化
目的:儘量減少重繪和重排的次數,限定範圍
div.style.left = '10px';
div.style.top = '10px';
div.style.width = '20px';
div.style.height = '20px';
這隻觸發一次重排,由於瀏覽器的渲染隊列機制,但是如果你在其中加入console就會觸發多次,然後清空渲染隊列,因爲console是立即執行渲染隊列機制。
- console和js分離,然後把重排改變的樣式集中寫,這樣可以把他們放在渲染隊列
- 讀寫分離
// bad 強制刷新 觸發兩次重排
div.style.left = div.offsetLeft + 1 + 'px';
div.style.top = div.offsetTop + 1 + 'px';
// good 緩存佈局信息 相當於讀寫分離
var curLeft = div.offsetLeft;
var curTop = div.offsetTop;
div.style.left = curLeft + 1 + 'px';
div.style.top = curTop + 1 + 'px';
- 操作DOM之前先隱藏DOM,或者通過DocumentFragment創建一個DOM碎片,在裏面完成重排然後在加入原來的DOM中。
- 用absolute和fixed重排使用性能少,優化動畫,開啓3d,比如實現一個動畫,以1個像素爲單位移動這樣最平滑,但是reflow就會過於頻繁,大量消耗CPU資源,如果以3個像素爲單位移動則會好很多。GPU 加速通常包括以下幾個部分:Canvas2D,佈局合成, CSS3轉換(transitions),CSS3 3D變換(transforms),WebGL和視頻(video)。
強制刷新style樣式
1.offsetTop, offsetLeft, offsetWidth, offsetHeight
2.scrollTop, scrollLeft, scrollWidth, scrollHeight
3.clientTop, clientLeft, clientWidth, clientHeight
4.getComputedStyle(), 或者 IE的 currentStyle