我們經(jīng)常說到瀏覽器的性能問題缚窿,其實(shí)與瀏覽器性能息息相關(guān)的一點(diǎn)就是瀏覽器如何渲染我們的網(wǎng)頁袍镀,這個(gè)時(shí)候我們就會(huì)涉及到一個(gè)概念聚谁,那就是瀏覽器的回流(重排评疗,以下統(tǒng)稱回流测砂,Reflow)與重繪(Repaint)。
回流
對(duì)回流這個(gè)詞百匆,我的理解是回爐重造砌些,即對(duì)于整個(gè)網(wǎng)頁重新渲染一遍。那我們可以思考一下加匈,從性能角度來講存璃,如果我們來寫瀏覽器的代碼,一定是再必須要重新渲染網(wǎng)頁的時(shí)候再重新渲染雕拼,那就推出一個(gè)問題纵东,什么時(shí)候?yàn)g覽器必須要重新渲染網(wǎng)頁?
其實(shí)必定是當(dāng)網(wǎng)頁的元素坐標(biāo)發(fā)生變化的時(shí)候啥寇,這里我們可以理解為有很多人在排隊(duì)篮迎,大家僅僅的依靠在一起,那什么時(shí)候大家需要都挪動(dòng)下位置呢示姿?我覺得要么就是一個(gè)人或者幾個(gè)人突然變胖了/瘦了,那大家如果想要繼續(xù)依靠在一起逊笆,就得都動(dòng)一動(dòng)栈戳;或者其中一個(gè)人或者幾個(gè)人挪動(dòng)了一下自己的位置,他勢(shì)必也會(huì)擠著其他人去動(dòng)一動(dòng)位置难裆。這種重新渲染全部或部分文檔的動(dòng)作我們就叫做回流子檀,因?yàn)榇蠹叶夹枰矂?dòng)下位置,也就導(dǎo)致我們這個(gè)網(wǎng)頁需要回爐重造了乃戈。
所以會(huì)導(dǎo)致回流的操作(包括但不限于):
頁面首次渲染
瀏覽器窗口大小發(fā)生改變
元素尺寸或位置發(fā)生改變
元素內(nèi)容變化(文字?jǐn)?shù)量或圖片大小等等)
元素字體大小變化
添加或者刪除可見的
DOM
元素激活
CSS
偽類(例如::hover
)
重繪
還是拿排隊(duì)舉例褂痰,當(dāng)隊(duì)伍中的一個(gè)人需要換一件衣服,比如他從穿黃衣服換成穿紅色的衣服症虑,這個(gè)時(shí)候只要這一個(gè)人換件衣服就行了缩歪,對(duì)其他人并沒有影響,這種情況我們就叫做重繪谍憔。瀏覽器只需要對(duì)該元素進(jìn)行重新繪制即可匪蝙。
所以會(huì)導(dǎo)致回流的操作(包括但不限于):
- 修改color/background-color/visibility
由上述可見,其實(shí)回流對(duì)瀏覽器性能的消耗是高于重繪的习贫,而且回流的操作一定會(huì)伴隨著重繪逛球,重繪卻不一定伴隨回流。那現(xiàn)代瀏覽器其實(shí)對(duì)這塊是有進(jìn)行優(yōu)化處理的苫昌,如果我們的隊(duì)伍總是需要變換位置颤绕,我們就統(tǒng)一來一次大排隊(duì)。
那么我們?cè)谄綍r(shí)的工作中,如果針對(duì)于回流和重繪寫出性能更好地代碼呢奥务?有以下幾點(diǎn)可以注意的:
CSS
避免使用
table
布局物独。盡可能在
DOM
樹的最末端改變class
。避免設(shè)置多層內(nèi)聯(lián)樣式汗洒。
將動(dòng)畫效果應(yīng)用到
position
屬性為absolute
或fixed
的元素上议纯。避免使用
CSS
表達(dá)式(例如:calc()
)。
JavaScript
避免頻繁操作樣式溢谤,最好一次性重寫
style
屬性瞻凤,或者將樣式列表定義為class
并一次性更改class
屬性。避免頻繁操作
DOM
世杀,創(chuàng)建一個(gè)documentFragment
阀参,在它上面應(yīng)用所有DOM操作
,最后再把它添加到文檔中瞻坝。也可以先為元素設(shè)置
display: none
蛛壳,操作結(jié)束后再把它顯示出來。因?yàn)樵?code>display屬性為none
的元素上進(jìn)行的DOM
操作不會(huì)引發(fā)回流和重繪所刀。避免頻繁讀取會(huì)引發(fā)回流/重繪的屬性衙荐,如果確實(shí)需要多次使用,就用一個(gè)變量緩存起來浮创。
對(duì)具有復(fù)雜動(dòng)畫的元素使用絕對(duì)定位忧吟,使它脫離文檔流,否則會(huì)引起父元素及后續(xù)元素頻繁回流斩披。
參考 瀏覽器的回流與重繪 (Reflow & Repaint)
博客地址 北落師門