前端開發的時候大量的操作dom會引起瀏覽器重繪(redraw)和重排(reflow) 。
在文檔重新加載的時候,瀏覽器引擎會解析html來生成dom樹,之后根據DOM元素的幾何屬性構建一棵用於渲染的樹。渲染樹的每個節點都有大小和邊距等屬性,類似於盒子模型(由於隱藏元素不需要顯示,渲染樹中並不包含DOM樹中隱藏的元素)。當渲染樹構建完成后,瀏覽器就可以將元素放置到正確的位置了,再根據渲染樹節點的樣式屬性繪制出頁面。由於瀏覽器的流布局,對渲染樹的計算通常只需要遍歷一次就可以完成。
重繪是一個元素外觀的改變所觸發的瀏覽器行為,例如改變visibility、outline、背景色等屬性。瀏覽器會根據元素的新屬性重新繪制,使元素呈現新的外觀。重繪不會帶來重新布局,並不一定伴隨重排。
重排是更明顯的一種改變,可以理解為渲染樹需要重新計算。下面是常見的觸發重排的操作:
DOM元素的幾何屬性變化
DOM元素的屬性變化時,瀏覽器會重新渲染該部分,而且會涉及到子節點/兄弟節點的重新計算。重排一定會引起瀏覽器的重繪,代價是很大的。
DOM樹的結構變化
DOM樹的增 刪 移動 ,會出發重排,瀏覽器引擎布局過程是從上到下的,從左到右的過程。 所以,如果在body最前面插入一個元素,會導致整個文檔的重新渲染,而在其后插入一個元素,則不會影響到前面的元素。
獲取某些屬性
當獲取一些屬性的時候, 為了取得正確的值,會進行重排。 offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)。所以,在多次使用這些值時應進行保存。
改變元素樣式 也會引起重排。
盡量減小重排次數和影響范圍:
將多次改變樣式屬性的操作合並成一次操作。
var changeDiv = document.getElementById(‘changeDiv’); changeDiv.style.color = ‘#093′; changeDiv.style.background = ‘#eee’; changeDiv.style.height = ’200px’; //也可以 新增一個class 一次增加class
將需要多次重排的元素,position屬性設為absolute或fixed,這樣此元素就脫離了文檔流,它的變化不會影響到其他元素。例如有動畫效果的元素就最好設置為絕對定位。
在需要經常獲取那些引起瀏覽器重排的屬性值時,要緩存到變量。
由於display屬性為none的元素不在渲染樹中,對隱藏的元素操作不會引發其他元素的重排。如果要對一個元素進行復雜的操作時,可以先隱藏它,操作完成后再顯示。這樣只在隱藏和顯示時觸發2次重排