【前端】重排和重绘
1. 什么是重排和重繪?
重排:若渲染樹的一部分更新,且尺寸變化,就會發生重排。
重繪:部分節點需要更新,但不改變其他集合形狀。如改變某個元素的vidibility、outline、背景顏色等,就會發生重繪。
PS:重繪不一定導致重排,但重排一定會導致重繪。重排會產生比重繪更大的開銷。
2. 重排和重繪何時會發生?
觸發重排:
(1)頁面第一次渲染:在頁面發生首次渲染的時候,所有組件都要進行首次布局,這是開銷最大的一次重排
(2)瀏覽器窗口尺寸改變
(3)元素位置和尺寸(寬、高、內外邊距、邊框等)發生改變的時候
(4)增加或刪除DOM節點
(5)內容發生改變(文字數量或圖片大小等等)
(6)元素字體大小變化
(7)激活CSS偽類(例如::hover)?
(8)增加或修改樣式,設置style屬性
(9)查詢某些屬性或調用某些方法,如:調用getComputedStyle方法,或者IE里的currentStyle時,也會觸發重排
(10)display:none(重排并重繪)
觸發重繪:
(1)vidibility
(2)outline
(3)背景顏色:color、background-color
(4)visibility:hidden(重排)
3. 如何減少重排和重繪以提升頁面性能?
(1)樣式集中改變:不要一個個修改屬性,應通過一個class來修改。
錯誤寫法:div.style.width="50px";div.style.top="60px"; 正確寫法:div.className+="modify";(2)DOM離線化:一旦我們給元素設置display:none時,元素不會存在于渲染樹中,相當于將其從頁面“拿掉”,我們之后的操作將不會觸發重排和重繪,這叫做DOM的離線化。
dom.display = 'none' // 修改dom樣式 dom.display = 'block'(3)批量添加DOM:通過使用DocumentFragment創建一個DOM碎片,在它上面批量操作DOM,操作完成之后,再添加到文檔中,這樣只會觸發一次重排。使用innerHTML永遠比DOM操作快。(特別注意:innerHTML不會執行字符串中的嵌入腳本,因此不會產生XSS漏洞)。
(4)復制節點,在副本中修改,然后直接替換當前的節點。
(5)降低受影響的節點:在頁面頂部插入節點將影響后續所有節點,而絕對定位元素的改變會影響較少的元素,將position屬性設置為absolute或fixed。
(6)分離讀寫操作。
div.style.top = "10px"; div.style.bottom = "10px"; div.style.right = "10px"; div.style.left = "10px"; console.log(div.offsetWidth); console.log(div.offseHeight); console.log(div.offsetRight); console.log(div.offsetLeft);原來的操作會導致四次重排和四次重繪,變換順序之后只會觸發一次重排 在第一個console的時候,瀏覽器把之前上面四個寫操作的渲染隊列都給清空了。因為渲染隊列本來就是空的,所以剩下的console并沒有觸發重排,僅僅拿值而已。?
(7)緩存布局信息。
// 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';(8)使用 css spirit,也叫 css 精靈,它將所有的圖片放到一張圖片上,然后通過定位來實現圖片的使用。
?
參考:
重繪和重拍
重排與重繪
重排和重繪
重繪重排重渲染?
END
總結
- 上一篇: 王者荣耀服务器维修多久,王者荣耀今天维护
- 下一篇: 灰色按键激活小程序