瀏覽器解析HTML的過程
1.構建 frame, 以建立DOM樹泡嘴。
2.回流(reflow) 引起Dom樹結構變化麸祷,改變頁面布局仅父。 3.重繪(repaint) 不會引起Dom樹變化及頁面布局變化用含,只重新渲染頁面樣式
回流與重繪兩者之間的聯系在于: 觸發(fā)回流一定會觸發(fā)重繪, 而觸發(fā)重繪卻不一定會觸發(fā)回流离咐。
我們可以把頁面理解為一個黑板谱俭,黑板上有一朵畫好的小花。現在我們要把這朵從左邊(left)移到了右邊(right)宵蛀,那我們是不是要先確定好右邊的具體位置昆著,畫好形狀(回流),再畫上它原有的顏色(重繪)术陶。
但如果我們僅僅是想換給花朵換一個顏色凑懂,那么只需擦掉花朵上的顏色,再重新涂上自己期望的顏色(重繪)就可以了梧宫。
1. 回流(Reflow)
當Render Tree中部分或全部元素的尺寸,結構或者某些屬性發(fā)生改變時,瀏覽器重新渲染部分或全部文檔的過程
導致回流發(fā)生的一些因素:
瀏覽器窗口大小發(fā)生改變
元素字體大小變化
增加或者移除樣式表
內容變化接谨,比如用戶在 input 框中輸入文字, CSS3 動畫,文字數量或者圖片大小改變等
激活
CSS
偽類塘匣,比如:hover
操作
class
屬性添加或刪除可見的DOM元素
計算
offsetWidth
和offsetHeight
屬性設置
style
屬性的值頁面首次渲染
元素尺寸或者位置發(fā)生改變
一些常用且會導致回流的屬性和方法:
clientWidth
,clientHeight
,clientTop
,clientLeft
offsetWidth
,offsetHeight
,offsetTop
,offsetLeft
scrollWidth
,scrollHeight
,scrollTop
,scrollLeft
,scrollIntoView()
2. 重繪(Repaint)
而重繪則是視覺效果變化引起的重新繪制脓豪。比如 color
或者 background
發(fā)生了變化,那就該給觸發(fā)重繪的元素化化妝忌卤,化成它想要的樣子扫夜。
3.性能影響
回流比重繪的代價要更高
有時僅僅回流一個單一的元素,它的父元素以及任何跟隨它的元素也會產生回流
現代瀏覽器會對頻繁的回流或重繪操作進行優(yōu)化:
瀏覽器會維護一個隊列,把所有引起回流和重繪的操作放入到隊列中,如果隊列中的任務數量或者時間間隔達到一個閾值,瀏覽器會將隊列清空,進行一次批處理,這樣可以把多次回流和重繪變成一次
4.如何避免回流和重繪
CSS:
1、避免使用table布局。 2历谍、盡可能在DOM樹的最末端改變class现拒。 3、避免設置多層內聯樣式望侈。 4、將動畫效果應用到position屬性為absolute或fixed的元素上勋桶。 5脱衙、避免使用CSS表達式(例如:calc())。
JavaScript:
1例驹、避免頻繁操作樣式捐韩,最好一次性重寫style屬性,或者將樣式列表定義為class并一次性更改class屬性鹃锈。 2荤胁、避免頻繁操作DOM,創(chuàng)建一個documentFragment屎债,在它上面應用所有DOM操作仅政,最后再把它添加到文檔中。 3盆驹、也可以先為元素設置display: none圆丹,操作結束后再把它顯示出來。因為在display屬性為none的元素上進行的DOM操作不會引發(fā)回流和重繪躯喇。 4辫封、避免頻繁讀取會引發(fā)回流/重繪的屬性,如果確實需要多次使用廉丽,就用一個變量緩存起來倦微。 5、對具有復雜動畫的元素使用絕對定位正压,使它脫離文檔流欣福,否則會引起父元素及后續(xù)元素頻繁回流。