注意:迴流必定會觸發重繪,而重繪不必定會迴流javascript
渲染樹發生變化,就會產生迴流或重繪,例如:php
display:none
(迴流和重繪都會觸發),visibility: hidden
(只有重繪,由於沒有幾何變化)再看一些例子:css
var bstyle = document.body.style;
bstyle.padding = "20px"; // 迴流,重繪
bstyle.border = "10px solid red"; // 再一次迴流和重繪
bstyle.color = "blue"; // 只有重繪,沒有顏色變化
bstyle.backgroundColor = "#fad"; // 重繪
bstyle.fontSize = "2em"; // 迴流,重繪
// 新加元素 - 迴流,重繪
document.body.appendChild(document.createTextNode('dude!'));
複製代碼
還有些迴流會帶來更多的性能損耗,好比你把頁面頂部的一個div設置了動畫或者拉大了,致使頁面下面其餘部分都下去了。java
由於渲染樹的迴流和重繪比較損耗,瀏覽器目標在於減少負面影響。一個策略就是根本不作這件事情,至少如今不作。瀏覽器把你寫的更改放在一個隊列裏而後批量執行。用這種方法將會把屢次須要迴流的更改合成一次迴流進行計算。瀏覽器可以把屢次更改放進隊列,而後隔一段時間或者達到必定數量時一次性處理掉。git
可是有時候,腳本(js)可能會阻止瀏覽器這項優化措施,致使它(立刻)清理隊列以及執行全部更改。這件事發生在你修改樣式信息,好比:github
offsetTop
, offsetLeft
, offsetWidth
, offsetHeight
scrollTop
/Left/Width/HeightclientTop
/Left/Width/HeightgetComputedStyle()
, 或者 currentStyle
in IE以上這些主要是獲取某個節點的樣式信息的,一旦你調用這些,瀏覽器都須要給你最新的值。爲了這樣作,瀏覽器就須要執行全部計劃中的更改,清理隊列執行迴流。瀏覽器
舉個例子,快速連續地獲取和設置樣式(循環中),好比:app
// no-no!
el.style.left = el.offsetLeft + 10 + "px";
複製代碼
幾條建議以下:oop
cssText
去作。// bad
var left = 10,
top = 10;
el.style.left = left + "px";
el.style.top = top + "px";
// better
el.className += " theclassname";
// 或者須要動態的修改top和left...
// better
el.style.cssText += "; left: " + left + "px; top: " + top + "px;";
複製代碼
以「離線」方式批量處理DOM更改。離線意思是不在真實的DOM樹下(作更改),你能夠:性能
documentFragment
去臨時存一下更改display:none
(須要一次迴流及重繪)隱藏掉元素,增長100次修改,而後再顯示(再花費一次迴流重繪)。這樣你就拿2次迴流和重繪換掉了100次。不要過度地使用computed styles。若是你須要使用,那就拿一次,而後保存到本地變量裏,並對這個本地變量進行操做。從新看下那個no-no例子:
// no-no!
for(big; loop; here) {
el.style.left = el.offsetLeft + 10 + "px";
el.style.top = el.offsetTop + 10 + "px";
}
// better
var left = el.offsetLeft,
top = el.offsetTop
esty = el.style;
for(big; loop; here) {
left += 10;
top += 10;
esty.left = left + "px";
esty.top = top + "px";
}
複製代碼