CSS的reflow和repaint
什么是reflow
瀏覽器為了重新渲染部分或整個(gè)頁面,重新計(jì)算頁面元素位置和幾何結(jié)構(gòu)的進(jìn)程叫做reflow.
通俗點(diǎn)說就是當(dāng)開發(fā)人員定義好了樣式后(也包括瀏覽器的默認(rèn)樣式),瀏覽器根據(jù)這些來計(jì)算并根據(jù)結(jié)果將元素放到它應(yīng)該出現(xiàn)的位置上,這個(gè)過程叫做reflow.
由于reflow是一種瀏覽器中的用戶攔截操作,所以我們了解如何減少reflow次數(shù),及DOM的層級(jí),css效率對(duì)refolw次數(shù)的影響是十分有必要的。
reflow(回流)是導(dǎo)致DOM腳本執(zhí)行效率低的關(guān)鍵因素之一,頁面上任何一個(gè)節(jié)點(diǎn)觸發(fā)了reflow,會(huì)導(dǎo)致它的子節(jié)點(diǎn)及祖先節(jié)點(diǎn)重新渲染。
<body>
<div class="hello">
<h4>hello</h4>
<p><strong>Name:</strong>BDing</p>
<h5>male</h5>
<ol>
<li>coding</li>
<li>loving</li>
</ol>
</div>
</body>
當(dāng)p節(jié)點(diǎn)上發(fā)生reflow時(shí),hello和body也會(huì)重新渲染,甚至h5和ol都會(huì)收到影響。
什么時(shí)候會(huì)導(dǎo)致reflow發(fā)生呢?
- 改變窗口大小
- 改變文字大小
- 添加/刪除樣式表
- 內(nèi)容的改變,(用戶在輸入框中寫入內(nèi)容也會(huì))
- 激活偽類,如:hover
- 操作class屬性
- 腳本操作DOM
- 計(jì)算offsetWidth和offsetHeight
- 設(shè)置style屬性
減少reflow對(duì)性能的影響的建議
盡可能限制reflow的影響范圍,盡可能在低層級(jí)的DOM節(jié)點(diǎn)上,上述例子中,如果你要改變p的樣式,class就不要加在div上,通過父元素去影響子元素不好。
避免設(shè)置大量的style屬性,因?yàn)橥ㄟ^設(shè)置style屬性改變結(jié)點(diǎn)樣式的話,每一次設(shè)置都會(huì)觸發(fā)一次reflow,所以最好是使用class屬性
實(shí)現(xiàn)元素的動(dòng)畫,它的position屬性,最好是設(shè)為absoulte或fixed,這樣不會(huì)影響其他元素的布局
動(dòng)畫實(shí)現(xiàn)的速度的選擇。比如實(shí)現(xiàn)一個(gè)動(dòng)畫,以1個(gè)像素為單位移動(dòng)這樣最平滑,但是reflow就會(huì)過于頻繁,大量消耗CPU資源,如果以3個(gè)像素為單位移動(dòng)則會(huì)好很多。
不要使用table布局,因?yàn)閠able中某個(gè)元素旦觸發(fā)了reflow,那么整個(gè)table的元素都會(huì)觸發(fā)reflow。那么在不得已使用table的場(chǎng)合,可以設(shè)置
table-layout:auto;或者是table-layout:fixed這樣可以讓table一行一行的渲染,這種做法也是為了限制reflow的影響范圍如果CSS里面有計(jì)算表達(dá)式,每次都會(huì)重新計(jì)算一遍,出發(fā)一次reflow
什么是repaint
repaint是在一個(gè)元素的外觀被改變,但沒有改變布局的情況下發(fā)生的,如改變了visibility、outline、background等。當(dāng)repaint發(fā)生時(shí),瀏覽器會(huì)驗(yàn)證DOM樹上所有其他節(jié)點(diǎn)的visibility屬性。
通俗來說,就是當(dāng)各種盒子的位置、大小以及其他屬性,例如顏色、字體都確定下來后,瀏覽器便把這些元素都按照各自的特性繪制一遍,于是頁面的內(nèi)容出現(xiàn)了,這個(gè)過程叫做repaint
附上blog的github地址
如果這篇文章對(duì)你有所幫助,希望你能給我一個(gè)star,如果你有啥建議,歡迎和我交流哦。??????