本文節(jié)選自蒂芙尼·布朗撰寫(xiě)的《CSS大師》一書(shū)。該書(shū)在全球各大書(shū)店有售,您也可以在此處購(gòu)買(mǎi)電子書(shū)版本。
CSS中某些屬性和值會(huì)觸發(fā)重排(reflow),這代價(jià)高昂,可能降低用戶界面的響應(yīng)速度——頁(yè)面渲染、動(dòng)畫(huà)流暢度和滾動(dòng)性能都會(huì)受到影響,尤其是在手機(jī)和平板電視等低功耗設(shè)備上。
什麼是重排? {.title}
重排是指任何更改頁(yè)面部分或全部佈局的操作。例如,更改元素的尺寸或更新其左側(cè)位置。它們會(huì)導(dǎo)致瀏覽器重新計(jì)算文檔中其他元素的高度、寬度和位置。
重繪(repaint)與重排類(lèi)似,都會(huì)強(qiáng)制瀏覽器重新渲染文檔的一部分。例如,當(dāng)鼠標(biāo)懸停在按鈕上時(shí)更改其顏色就是一個(gè)重繪操作。重繪比重排影響較小,因?yàn)樗粫?huì)影響節(jié)點(diǎn)的尺寸或位置;但是,重繪也應(yīng)盡量減少。
重排和重繪通常由DOM操作觸發(fā),例如添加或刪除元素。但它們也可能由影響元素尺寸、可見(jiàn)性或位置的屬性更改引起。無(wú)論更改是由JavaScript還是基於CSS的動(dòng)畫(huà)引起的,情況都是如此。
注意:頁(yè)面加載{.title}
頁(yè)面加載時(shí),瀏覽器解析初始HTML、CSS和JavaScript,始終會(huì)觸發(fā)重排和重繪。
要完全避免項(xiàng)目中的重繪和重排是困難的。但是,我們可以使用時(shí)間線工具來(lái)識(shí)別它們並減少它們的影響。
時(shí)間線工具{.title}
時(shí)間線工具起初可能有點(diǎn)令人困惑。它們測(cè)量前端的性能,記錄各種任務(wù)完成所需的時(shí)間。通過(guò)在與頁(yè)面交互時(shí)記錄活動(dòng),我們可以找出哪些CSS代碼可能導(dǎo)致性能瓶頸。
要使用時(shí)間線,請(qǐng)點(diǎn)擊開(kāi)發(fā)者工具界面中的時(shí)間線選項(xiàng)卡。在Chrome、Opera和Firefox中,它被恰當(dāng)?shù)孛麨椤皶r(shí)間線”。 Safari將其命名為複數(shù)形式“時(shí)間線”。 Internet Explorer 11 使用更具描述性的名稱“UI響應(yīng)能力”。 [9]
在任何瀏覽器中,按“記錄”按鈕開(kāi)始記錄過(guò)程。與頁(yè)面有問(wèn)題的部分交互,完成後,單擊相應(yīng)的按鈕停止記錄。
根據(jù)您使用的瀏覽器,您可能會(huì)立即看到數(shù)據(jù),或者在停止記錄後看到數(shù)據(jù)。 Safari和Firefox實(shí)時(shí)顯示數(shù)據(jù),而Chrome、Opera和Internet Explorer在您停止記錄後呈現(xiàn)性能圖表。
文檔加載、函數(shù)調(diào)用、DOM事件、樣式重新計(jì)算和繪製操作都會(huì)在每個(gè)瀏覽器中記錄,從而讓我們概述性能瓶頸。就CSS性能而言,我們至少要關(guān)注兩個(gè)相關(guān)的方面:
- 大量的樣式重新計(jì)算和繪製操作
- 耗時(shí)較長(zhǎng)的操作,時(shí)間線中較大的塊表示
為了了解實(shí)際情況,我們將比較兩個(gè)基本文檔,示例A和示例B。在這兩種情況下,我們都將一系列div{.literal}元素從x位置0移動(dòng)到x位置1000。兩個(gè)示例都使用CSS轉(zhuǎn)換。但是,在示例A中,我們將對(duì)left
屬性進(jìn)行動(dòng)畫(huà)處理。在示例B中,我們將使用轉(zhuǎn)換變換並對(duì)transform
屬性進(jìn)行動(dòng)畫(huà)處理。
兩個(gè)示例的標(biāo)記相同(結(jié)果如圖3.16所示):
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<title>Performance example</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<button type="button" id="move">Move</button>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<??>
</body>
</html>
圖3.16. Safari瀏覽器中我們的HTML演示頁(yè)面,包含div元素兩個(gè)文檔的JavaScript代碼也相同。單擊“移動(dòng)”按鈕會(huì)在每個(gè)div元素上切換moved
類(lèi):
var move = document.getElementById('move');
move.addEventListener('click', function(e) {
var objs = document.body.querySelectorAll('div');
Array.prototype.forEach.call(objs, function(o){
o.classList.toggle('moved');
});
});
我們的CSS代碼是兩者不同的部分。示例A使用的CSS如下:
div {
background: #36f;
margin-bottom: 1em;
width: 30px;
height: 30px;
position: relative;
left: 0;
transition: left 2s ease-in;
}
.moved {
left: 1000px;
}
觸發(fā)後,此動(dòng)畫(huà)將在我們的時(shí)間線中生成大量樣式計(jì)算和重繪指示器。下面的圖片顯示了Safari(圖3.17)、Chrome(圖3.18)、Internet Explorer(圖3.19)和Firefox(圖3.20)中此轉(zhuǎn)換的時(shí)間線輸出。
圖3.17. Safari瀏覽器中左側(cè)位置轉(zhuǎn)換的時(shí)間線輸出
圖3.18. Chrome瀏覽器中的相同輸出
圖3.19. Internet Explorer 11瀏覽器中左側(cè)位置轉(zhuǎn)換的時(shí)間線輸出
圖3.20. Firefox瀏覽器中的輸出樣式計(jì)算和重繪的原因與我們正在轉(zhuǎn)換的屬性有關(guān):left
。 left
屬性在更改時(shí)會(huì)觸發(fā)重排,即使更改是由動(dòng)畫(huà)或轉(zhuǎn)換引起的也是如此。
現(xiàn)在,讓我們看一下示例B的CSS:
div {
background: #f3f;
margin-bottom: 1em;
width: 30px;
height: 30px;
position: relative;
left: 0;
transition: transform 2s ease-in;
transform: translateX(0);
}
.moved {
transform: translateX(1000px);
}
在這裡,我們使用轉(zhuǎn)換並在translateX(0)
和translateX(1000px)
之間進(jìn)行轉(zhuǎn)換。
在大多數(shù)瀏覽器中,轉(zhuǎn)換不會(huì)觸發(fā)重排,我們的時(shí)間線將包含更少的重繪操作。這在Safari(圖3.21)、Chrome(圖3.22)和Internet Explorer(圖3.23)中很明顯。 Firefox是例外;比較圖3.20和圖3.24。左側(cè)轉(zhuǎn)換和轉(zhuǎn)換變換的時(shí)間線非常相似。
圖3.21. Safari瀏覽器中-webkit-transform
屬性轉(zhuǎn)換的時(shí)間線輸出
圖3.22. Chrome瀏覽器中使用transform
屬性的相同輸出
圖3.23. Internet Explorer 11瀏覽器中的輸出
圖3.24. Firefox瀏覽器中transform
屬性轉(zhuǎn)換的時(shí)間線輸出###識(shí)別要移除的代碼行{.title}
不幸的是,沒(méi)有明確的列表說(shuō)明哪些屬性會(huì)導(dǎo)致重排和重繪。 Paul Lewis的CSS Triggers最接近,但它是Chrome專(zhuān)用的。但是,瀏覽器對(duì)於許多這些屬性的行為確實(shí)相似,因此此資源至少可以讓您了解哪些屬性可能導(dǎo)致問(wèn)題。
一旦您知道哪些屬性可能有問(wèn)題,下一步就是測(cè)試假設(shè)。使用註釋或添加臨時(shí)x-
前綴來(lái)禁用該屬性,然後重新運(yùn)行時(shí)間線測(cè)試。
請(qǐng)記住,性能是相對(duì)的,而不是絕對(duì)的或完美的。目標(biāo)是改進(jìn):使其性能比以前更好。如果屬性或效果的性能慢到無(wú)法接受,則將其完全刪除。
以上是調(diào)試UI響應(yīng)的CSS的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!