DOM樹:表示頁(yè)面結(jié)構(gòu)鹅心。
渲染樹:表示DOM節(jié)點(diǎn)如何顯示肄梨。
定義
當(dāng)DOM元素影響了元素的幾何屬性(例如寬和高)奥邮,瀏覽器需要重新計(jì)算元素的幾何屬性崔涂,同樣其它元素的幾何屬性也會(huì)和位置也會(huì)因此受到影響。瀏覽器會(huì)使渲染樹中受到影響的部分失效糊秆,并重新構(gòu)造渲染樹武福。這個(gè)過(guò)程稱為“重排”。
完成重排后痘番,瀏覽器會(huì)重新繪制受影響的部分到屏幕上中捉片,該過(guò)程稱為“重繪”。
- 重排發(fā)生的情況:
- 添加或刪除可見的DOM元素汞舱。
- 元素位置改變伍纫。
- 元素的尺寸改變(包括:內(nèi)外邊距、邊框厚度昂芜、寬度莹规、高度等屬性的改變)。
- 內(nèi)容改變泌神。
- 頁(yè)面渲染器初始化良漱。
- 瀏覽器窗口尺寸改變。
- 重繪發(fā)生的情況:
重繪發(fā)生在元素的可見的外觀被改變欢际,但并沒有影響到布局的時(shí)候母市。比如,僅修改DOM元素的字體顏色(只有Repaint损趋,因?yàn)椴恍枰{(diào)整布局)
優(yōu)化辦法
-
fragment元素的應(yīng)用
<ul id='fruit'>
<li> apple </li>
<li> orange </li>
</ul>
如果代碼中要添加內(nèi)容為peach患久、watermelon兩個(gè)選項(xiàng),你會(huì)怎么做浑槽?
傳統(tǒng)做法:
var lis = document.getElementById('fruit');
var li = document.createElement('li');
li.innerHTML = 'peach';
lis.appendChild(li);var li = document.createElement('li'); li.innerHTML = 'watermelon'; lis.appendChild(li);
很容易想到如上代碼蒋失,但是很顯然,重排了兩次括荡。隱藏的元素不在渲染樹中高镐,太棒了,我們可以先把id為fruit的ul元素隱藏畸冲,然后添加li元素嫉髓,最后再顯示观腊,但是實(shí)際操作中可能會(huì)出現(xiàn)閃動(dòng),原因這也很容易理解算行。這時(shí)梧油,fragment元素就有了用武之地了。
var fragment = document.createDocumentFragment();
var li = document.createElement('li');
li.innerHTML = 'peach';
fragment.appendChild(li);
var li = document.createElement('li');
li.innerHTML = 'watermelon';
fragment.appendChild(li);
document.getElementById('fruit').appendChild(fragment);
文檔片段的一個(gè)便利的語(yǔ)法特性是當(dāng)你附加一個(gè)片斷到節(jié)點(diǎn)時(shí)州邢,實(shí)際上被添加的是該片斷的子節(jié)點(diǎn)儡陨,而不是片斷本身。只觸發(fā)了一次重排量淌,而且只訪問(wèn)了一次實(shí)時(shí)的DOM骗村。
- 緩存布局信息
例如myElement元素沿對(duì)角線移動(dòng),每次移動(dòng)一個(gè)像素呀枢。到500*500像素的位置結(jié)束胚股。timeout循環(huán)體中可以這么做
myElement.style.left = 1 + myElement.offsetLeft + 'px';
myElement.style.top = 1 + myElement.offsetTop + 'px';
if(myElement.offsetLeft >= 500){
stopAnimation();
}
顯然這種方法低效,每次移動(dòng)都要查詢偏移量裙秋,導(dǎo)致瀏覽器刷新渲染隊(duì)列而不利于優(yōu)化琅拌。好的辦法是獲取一次起始位置的值,然后賦值給一個(gè)變量摘刑。如下
var current = myElement.offsetLeft;
current++;
myElement.style.left = current + 'px';
myElement.style.top = current + 'px';
if(myElement.offsetLeft >= 500){
stopAnimation();
} - 讓元素脫離文檔流
使用絕對(duì)位置定位頁(yè)面上的動(dòng)畫元素进宝,將其脫離文檔流。觸發(fā)一小區(qū)域的重繪枷恕。