一、瀏覽器渲染原理和關(guān)鍵渲染路徑
瀏覽器渲染原理:
讀取html,css文本与斤,構(gòu)建DOM樹。(DOM ,CSSOM)- DOMtree
關(guān)鍵渲染路徑:
javascript(觸發(fā)視覺變化) - style(樣式計(jì)算撩穿,css改變) - Layout(布局)- Paint(繪制)- Composite(合層)
二磷支、 回流與重繪, 如何避免布局抖動(dòng)
布局關(guān)心的是位置和大小。(如css:height食寡,offset改變位置雾狈,大小)抵皱,所以如果只是更改background善榛,opcity,不需要Layout(布局)呻畸,只需Paint(重繪)移盆。
回流:首次加載叫布局。再次叫回流伤为。影響回流的操作:
1咒循、 添加/刪除 元素
2、 操作styles钮呀,display:none
3剑鞍、 offsetLeft昨凡,offsetTop 爽醋,scrollTop,clientWidth便脊。使用這些屬性蚂四,會(huì)引起強(qiáng)制布局更新
4、 移動(dòng)元素位置
5哪痰、 修改瀏覽器大小遂赠,字體
通過Chrome devtools,performance性能檢測(cè)主線程任務(wù)查看回流的過程
連續(xù)的讀寫DOM屬性(width,offsetTop等)晌杰,會(huì)引起強(qiáng)制的布局更新跷睦,強(qiáng)制布局更新會(huì)造成頁面抖動(dòng) layout thrashing
使用FastDom 解決布局抖動(dòng), https://github.com/wilsonpage/fastdom
三、復(fù)合線程(compositor thread)與圖層(layers)
復(fù)合就是把頁面拆成多個(gè)圖層肋演,圖層之間是互不影響的抑诸。只繪制自己的那個(gè)圖層,再進(jìn)行復(fù)合爹殊。圖層拆分默認(rèn)是瀏覽器來做蜕乡,如果某個(gè)元素對(duì)其他元素影響比較大,建立獨(dú)立圖層梗夸。
查看圖層
四层玲、減少重繪 repaint
可以利用圖層,避免回流,只觸發(fā)復(fù)合辛块,不觸發(fā)回流與重繪畔派。可以采用如下樣式代替:
position:transform:translate(x,y)
Scale:transform:scale(n)
Rotation:transform:rotate(n deg)
Opacity:Opacity : 0….1
Css屬性 will-change: transform - 告訴瀏覽器提到單獨(dú)的圖層
先看一個(gè)有回流的動(dòng)畫
打開頁面 Chrome devtools憨降,performance 錄制功能
沒有回流的動(dòng)畫
修改css 樣式
.box {
display: flex;
justify-content: space-around;
will-change: transform;
}
.box .img {
width: 300px;
height: 300px;
}
.img:hover {
transform: scale(1.5, 1);
transition: all 2s;
}
再進(jìn)行performance 錄制功能
查看主線程 task任務(wù)此時(shí)沒有布局和繪制了父虑,查看網(wǎng)頁圖層多了一個(gè)box圖層
查看重繪:Chrome devtools ctrl shift p -> show rendering
JS操作避免回流、重繪
1授药、避免使用JS一個(gè)樣式修改完接著改下一個(gè)樣式士嚎,最好一次性更改CSS樣式,或者將樣式列表定義為class的名稱
2悔叽、避免頻繁操作DOM莱衩,使用文檔片段創(chuàng)建一個(gè)子樹,然后再拷貝到文檔中
3娇澎、先隱藏元素笨蚁,進(jìn)行修改后再顯示該元素,因?yàn)閐isplay:none上的DOM操作不會(huì)引發(fā)回流和重繪
4趟庄、避免循環(huán)讀取offsetLeft等屬性括细,在循環(huán)之前把它們存起來
5、對(duì)于復(fù)雜動(dòng)畫效果,使用絕對(duì)定位讓其脫離文檔流戚啥,否則會(huì)引起父元素及后續(xù)元素大量的回流