33.哪些操作会引起页面回流(Reflow)
一、前言
偶爾在面試過程中遇到過重匯與回流reflow的問題,畢竟頁面優(yōu)化也是考核一個開發(fā)者能力的關(guān)鍵之一,上篇文章聊了下documentfragment也是為了減輕回流問題,那么本篇文章好好介紹下重繪和回流。
二、重繪和回流是什么
怎么去理解這兩個概念呢?從字面上理解,重繪,重新繪畫,重新上色,較難產(chǎn)生聯(lián)想的是回流。
我們都知道,一個頁面從加載到完成,首先是構(gòu)建DOM樹,然后根據(jù)DOM節(jié)點的幾何屬性形成render樹(渲染樹),當(dāng)渲染樹構(gòu)建完成,頁面就根據(jù)DOM樹開始布局了,渲染樹也根據(jù)設(shè)置的樣式對應(yīng)的渲染這些節(jié)點。
在這個過程中,回流與DOM樹,渲染樹有關(guān),重繪與渲染樹有關(guān),怎么去理解呢?
比如我們增刪DOM節(jié)點,修改一個元素的寬高,頁面布局發(fā)生變化,DOM樹結(jié)構(gòu)發(fā)生變化,那么肯定要重新構(gòu)建DOM樹,而DOM樹與渲染樹是緊密相連的,DOM樹構(gòu)建完,渲染樹也會隨之對頁面進行再次渲染,這個過程就叫回流。
當(dāng)你給一個元素更換顏色,這樣的行為是不會影響頁面布局的,DOM樹不會變化,但顏色變了,渲染樹得重新渲染頁面,這就是重匯。
你應(yīng)該能感覺到,回流的代價要遠大于重繪。且回流必然會造成重繪,但重繪不一定會造成回流。
題外話
1.由于display為none的元素在頁面不需要渲染,渲染樹構(gòu)建不會包括這些節(jié)點;但visibility為hidden的元素會在渲染樹中。因為display為none會脫離文檔流,visibility為hidden雖然看不到,但類似與透明度為0,其實還在文檔流中,還是有渲染的過程。
2.盡量避免使用表格布局,當(dāng)我們不為表格td添加固定寬度時,一列的td的寬度會以最寬td的寬作為渲染標(biāo)準(zhǔn),假設(shè)前幾行td在渲染時都渲染好了,結(jié)果下面某行的一個td特別寬,table為了統(tǒng)一寬,前幾行的td會回流重新計算寬度,這是個很耗時的事情。
三、重繪和回流有什么區(qū)別
結(jié)合上面的解釋,引起DOM樹結(jié)構(gòu)變化,頁面布局變化的行為叫回流,且回流一定伴隨重繪。
只是樣式的變化,不會引起DOM樹變化,頁面布局變化的行為叫重繪,且重繪不一定會便隨回流。
它們的區(qū)別就像這樣:
回流往往伴隨著布局的變化,代價較大
重繪只是樣式的變化,結(jié)構(gòu)不會變化
四、怎么減少回流
說了這么多,我們也知道了,回流要重新構(gòu)建DOM樹,渲染樹也得重新渲染,很麻煩,哪么哪些行為會引起回流,怎么去避免呢?
1.DOM的增刪行為
比如你要刪除某個節(jié)點,給某個父元素增加子元素,這類操作都會引起回流。如果要加多個子元素,最好使用documentfragment。
2.幾何屬性的變化
比如元素寬高變了,border變了,字體大小變了,這種直接會引起頁面布局變化的操作也會引起回流。如果你要改變多個屬性,最好將這些屬性定義在一個class中,直接修改class名,這樣只用引起一次回流。
3.元素位置的變化
修改一個元素的左右margin,padding之類的操作,所以在做元素位移的動畫,不要更改margin之類的屬性,使用定位脫離文檔流后改變位置會更好。
4.獲取元素的偏移量屬性
例如獲取一個元素的scrollTop、scrollLeft、scrollWidth、offsetTop、offsetLeft、offsetWidth、offsetHeight之類的屬性,瀏覽器為了保證值的正確也會回流取得最新的值,所以如果你要多次操作,最取完做個緩存。
5.頁面初次渲染
這樣的回流無法避免
6.瀏覽器窗口尺寸改變
resize事件發(fā)生也會引起回流。
這里就不列舉引起重繪的行為了,記住,回流一定伴隨著重繪,所以上面的行為都會重繪,除此之外,例如修改背景顏色,字體顏色之類不影響布局的行為都只引發(fā)重繪。
如果對于documentfragment文檔片段感興趣,可以閱讀博主這篇文章
總結(jié)
以上是生活随笔為你收集整理的33.哪些操作会引起页面回流(Reflow)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android使用NDK---函数参数传
- 下一篇: 使用NDK编译VTK