關於DOM的操作以及效能優化問題-重繪重排
為什麼dom操作會影響效能?
在瀏覽器當中,dom的實現和ECMAScript的實現是分離的。
例如,在IE中,ECMAScrit的實現在jscript.dll中,而DOM的實現在mshtml.dll中;在Chrome中使用WebKit中的 WebCore處理DOM和渲染,但ECMAScript是在V8引擎中實現的,其他瀏覽器的情況類似。
因此,操作dom,就是通過js程式碼呼叫dom的介面,就相當於兩個相互獨立的模組發生了互動。這樣,相比於在同一個模組當中互相呼叫,這種跨模組的呼叫它的效能損耗是非常高的。
把DOM和JavaScript(這裡指ECMScript)各自想象為一個島嶼,它們之間用收費橋樑連線,ECMAScript每次訪問DOM,都要途徑這座橋,並交納“過橋費”,訪問DOM的次數越多,費用也就越高。因此,推薦的做法是儘量減少過橋的次數,努力待ECMAScript島上。
然而,dom操作影響效能最主要是因為它導致了瀏覽器的重繪(repaint)和重排(reflow)。
瀏覽器渲染原理
為了可以更加深刻地理解重繪和重排對效能的影響,需要簡單瞭解一下瀏覽器的渲染原理。
從下載文件到渲染頁面的過程中,瀏覽器會通過解析HTML文件來構建DOM樹,解析CSS產生CSS規則樹。JavaScript程式碼在解析過程中, 可能會修改生成的DOM樹和CSS規則樹。之後根據DOM樹和CSS規則樹構建渲染樹,在這個過程中CSS會根據選擇器匹配HTML元素。渲染樹包括了每 個元素的大小、邊距等樣式屬性,渲染樹中不包含隱藏元素及head元素等不可見元素。最後瀏覽器根據元素的座標和大小來計算每個元素的位置,並繪製這些元 素到頁面上。無論何時總會有一個初始化的頁面佈局伴隨著一次繪製。
重繪
重繪,就是指頁面某些部分需要重新繪製,由於節點的幾何屬性發生改變或者由於樣式發生改變,例如改變元素背景色時,螢幕上的部分內容需要更新,而元素的位置和尺寸並沒有改變。
重排
元素的位置或尺寸發生了改變,瀏覽器需 要重新計算渲染樹,導致渲染樹的一部分或全部發生變化。渲染樹重新建立後,瀏覽器會重新繪製頁面上受影響的元素。
也就是說,重排,改變的是dom文件的結構,例如dom元素的位置或者尺寸發生了變化,需要重新佈局,就會發生重排。
優化方法:
1、將dom操作積累起來作批量操作
現代瀏覽器中會有優化方法,就是把dom操作積累起來,做批量處理。但是在有些情況下,瀏覽器會立即重排或重繪。比如請求如下的DOM元素佈局資訊:offsetTop/Left/Width/Height、scrollTop/Left/Width/Height、clientTop/Left/Width/Height、getComputedStyle()或 currentStyle。因為這些值都是動態計算的,所以瀏覽器需要儘快完成頁面的繪製,然後計算返回值,從而打亂了重排或重繪的優化。
2、合併多次的DOM操作為單次的DOM操作
最常見頻繁進行DOM操作的是頻繁修改DOM元素的樣式,程式碼類似如下:
element.style.borderColor = '#f00';
element.style.borderStyle = 'solid';
element.style.borderWidth = '1px';
這種編碼方式會因為頻繁更改DOM元素的樣式,觸發頁面多次的重排或重繪,上面介紹過,現代瀏覽器針對這種情況有效能的優化,它會合並DOM操作,但並不是所有的瀏覽器都存在這樣的優化。推薦的方式是把DOM操作儘量合併,如上的程式碼可以優化為:
// 優化方案1
element.style.cssText += 'border: 1px solid #f00;';
// 優化方案2
element.className += 'empty';
示例的程式碼有兩種優化的方案,都做到了把多次的樣式設定合併為一次設定。方案2比方案1稍微有一些效能上的損耗,因為它需要查詢CSS類。但方案2的維護性最好,這在上一章曾經討論過。很多時候,如果效能問題並不突出,選擇編碼方案時需要優先考慮的是程式碼的維護性。
類似的操作還有通過innerHTML介面修改DOM元素的內容。不要直接通過此介面來拼接HTML程式碼,而是以字串方式拼接好程式碼後,一次性賦值給DOM元素的innerHTML介面。
3、使用文件片段
文件片段是一個輕量級的document物件,並不會和特定的頁面關聯。通過在文件片段上進行DOM操作,可以降低DOM操作對頁面效能的影響,這 種方式是建立一個文件片段,並在此片段上進行必要的DOM操作,操作完成後將它附加在頁面中。對頁面效能的影響只存在於最後把文件片段附加到頁面的這一步 操作上。程式碼類似如下:
var fragment = document.createDocumentFragment();
// 一些基於fragment的大量DOM操作
...
document.getElementById('myElement').appendChild(fragment);
4、通過設定DOM元素的display樣式為none來隱藏元素
這種方式是通過隱藏頁面的DOM元素,達到在頁面中移除元素的效果,經過大量的DOM操作後恢復元素原來的display樣式。對於這類會引起頁面重繪或重排的操作,就只有隱藏和顯示DOM元素這兩個步驟了。程式碼類似如下:
var myElement = document.getElementById('myElement');
myElement.style.display = 'none';
// 一些基於myElement的大量DOM操作
...
myElement.style.display = 'block';
5、克隆DOM元素到記憶體中
這種方式是把頁面上的DOM元素克隆一份到記憶體中,然後再在記憶體中操作克隆的元素,操作完成後使用此克隆元素替換頁面中原來的DOM元素。這樣一來,影響效能的操作就只是最後替換元素的這一步操作了,在記憶體中操作克隆元素不會引起頁面上的效能損耗。程式碼類似如下:
var old = document.getElementById('myElement');
var clone = old.cloneNode(true);
// 一些基於clone的大量DOM操作
...
old.parentNode.replaceChild(clone, old);
6、設定具有動畫效果的DOM元素的position屬性為fixed或absolute
把頁面中具有動畫效果的元素設定為絕對定位,使得元素脫離頁面佈局流,從而避免了頁面頻繁的重排,只涉及動畫元素自身的重排了。這種做法可以提高動 畫效果的展示效能。如果把動畫元素設定為絕對定位並不符合設計的要求,則可以在動畫開始時將其設定為絕對定位,等動畫結束後恢復原始的定位設定。在很多的 網站中,頁面的頂部會有大幅的廣告展示,一般會動畫展開和摺疊顯示。如果不做效能的優化,這個效果的效能損耗是很明顯的。使用這裡提到的優化方案,則可以 提高效能。
相關推薦
揭露DOM操作以及效能優化
我們都知道:JavaScript DOM操作的效率是很低的,而且不是一般的慢,而且這也是引發效能問題的常見問題之一。為什麼會慢呢?因為對DOM的修改為影響網頁的使用者介面,重繪頁面是最昂貴的瀏覽器操作之一。 在討論頁面重繪、重排之前。需要對頁面的呈現流程有些瞭
關於DOM的操作以及效能優化問題-重繪重排
為什麼dom操作會影響效能? 在瀏覽器當中,dom的實現和ECMAScript的實現是分離的。 例如,在IE中,ECMAScrit的實現在jscript.dll中,而DOM的實現在mshtml.dll中;在Chrome中使用WebKit中的 WebCore處理DOM和渲染
關於DOM操作的效能優化
最著名的有關用js操作dom的觀點是:js和dom是獨立的小島,用橋實現兩者的聯絡,但橋很窄,要過路費,所以我們要盡最大可能減少過橋的次數。下面程式碼演示了用js操作dom的innerHTML,且一下修改5000次: <!DOCTYPE html> <h
display和visibility的區別以及迴流和重繪
display:none會脫離文件流,不佔據頁面空間; visibility:hidden,只是隱藏內容,並沒有脫離文件流,會佔據頁面的空間。 講述迴流以及重繪之前需要先了解頁面在文件載入完成之後到完全顯示中間的過程: 1.根據文件生成DOM樹(包括display:none的節點) 2.在D
【redis常用的鍵值操作及效能優化】
服務端 啟動redis服務 { // -a:指定密碼 -h:指定主機 -p:指定埠 } //讓redis 服務中斷崩潰 //儲存和關閉 //後臺備份 //設定登入密碼 //redis-benchmark :效能測試 &
瀏覽器渲染之重繪重排
重繪和重排定義 重繪:當渲染樹中的元素外觀(如:顏色)發生改變,不影響佈局時,產生重繪 迴流:當渲染樹中的元素的佈局(如:尺寸、位置、隱藏/狀態狀態)發生改變時,產生重繪迴流 注意:JS獲取Layout屬性值(如:offsetLeft、scrollTop、ge
elasticsearch核心知識--22.mget批量查詢api以及效能優化
批量查詢的好處就是一條一條的查詢,比如說要查詢100條資料,那麼就要傳送100次網路請求,這個開銷還是很大的如果進行批量查詢的話,查詢100條資料,就只要傳送1次網路請求,網路請求的效能開銷縮減100倍mget的語法(1)一條一條的查詢GET /test_index/test
css 頁面重繪和回流(重排)以及優化
有用 其他 第一次 pos fix 更新 幾何 完成 進行 一、html頁面的呈現流程 1. 瀏覽器把獲取到的HTML代碼解析成1個DOM樹,HTML中的每個tag都是DOM樹中的1個節點,根節點就是我們常用的document對象。DOM樹裏包含了所有HTML標簽,包
前端效能優化之重排和重繪
前言,最近利用碎片時間拜讀了一下尼古拉斯的另一鉅作《高效能JavaScript》,今天寫的文章從“老生常談”的頁面重繪和重排入手,去探究這兩個概念在頁面效能提升上的作用。 一.重排 & 重繪 有經驗的大佬對這個概念一定不會陌生,“瀏覽器輸入URL發生了什麼”。估計大家已經爛熟於
css 頁面重繪和迴流(重排)以及優化
一、html頁面的呈現流程 1. 瀏覽器把獲取到的HTML程式碼解析成1個DOM樹,HTML中的每個tag都是DOM樹中的1個節點,根節點就是我們常用的document物件。DOM樹裡包含了所有HTML標籤,包括display:none隱藏,還有用JS動態新增的元素等
瀏覽器渲染原理(效能優化之如何減少重排和重繪)
繼續上篇《瀏覽器位址列裡輸入URL後的全過程》 前言 為什麼要了解瀏覽器的渲染原理?瞭解瀏覽器的渲染原理有什麼好處?我們做前端開發為什麼非要了解瀏覽器的原理?直接把網頁做出來,什麼需求,直接一把梭,擼完收工不好嗎。 但是經常會有人會問,什麼是重排和重繪? 重排也叫迴流(Re
頁面重繪和回流以及優化(轉)
圖片大小 處理流 create 意圖 borde 基本上 nal arch 似的 源文章地址:http://www.css88.com/archives/4996 在討論頁面重繪、回流之前。需要對頁面的呈現流程有些了解,頁面是怎麽把html結合css等顯示到瀏覽器上的,下面
頁面重繪和回流以及優化
inf title col try 至少 com round 繪制 邊框 頁面重繪和回流以及優化 回流與重繪 1. 當render tree中的一部分(或全部)因為元素的規模尺寸,布局,隱藏等改變而需要重新構建。這就稱為回流(reflow)。每個頁面至少需要一次回流,就是在
html頁面重繪和迴流以及優化
在討論頁面重繪、迴流之前。需要對頁面的呈現流程有些瞭解,頁面是怎麼把html結合css等顯示到瀏覽器上的,下面的流程圖顯示了瀏覽器對頁面的呈現的處理流程。可能不同的瀏覽器略微會有些不同。但基本上都是類似的。 1.瀏覽器把獲取到的HTML程式碼解析成1個DOM樹,HTML中的每個tag都是D
記錄一下前端效能優化-為何操作DOM會變慢?
對於大多數前端來說,效能優化的方法可能包括以下這些: 減少HTTP請求(合併css、js,雪碧圖/base64圖片) 壓縮(css、js、圖片皆可壓縮) 樣式表放頭部,指令碼放底部 使用CDN(這部分,不少前端都不用考慮,負責釋出的兄弟可能會負責搞好) 快取…… 不僅要避
前端性能優化之重排和重繪
doc 重復 立即執行 selector add 顯示與隱藏 one 改變樣式 ref 前言,最近利用碎片時間拜讀了一下尼古拉斯的另一巨作《高性能JavaScript》,今天寫的文章從“老生常談”的頁面重繪和重排入手,去探究這兩個概念在頁面性能提升上的作用。 一.重排 &a
前端效能優化第二篇-迴流和重繪
前端效能優化第二篇-迴流和重繪 先給自己持續更新的專欄打個廣告,歡迎大家讀一讀專欄中的其他文章,戳一戳->前端效能優化 瀏覽器渲染過程 先請今天的主角“迴流”和“重繪”在後臺等一下,我們先來看看瀏覽器渲染頁面的過程,不要跳過這個重要的部分啊~ 當瀏覽器
瀏覽器重繪與重排的效能優化
重繪與重排 當DOM變化影響了元素的幾何屬性(寬、高改變等等) 瀏覽器此時需要重新計算元素幾何屬性 並且頁面中其他元素的幾何屬性可能會受影響 這樣渲染樹就發生了改變,也就是重新構造RenderTree渲染樹 這個過程叫做重排(reflow) 如果DOM變化僅僅
重繪和迴流以及如何優化
1、瀏覽器渲染機制 瀏覽器採用流式佈局模型(Flow Based Layout) 瀏覽器會把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合併就產生了渲染樹(Render Tree)。 有了RenderTree,我們就知道了所有節點的樣式,然後計算他們在頁面上的大小和位置,最後把節點繪製到
從瀏覽器渲染原理,淺談迴流重繪與效能優化
目錄 前言 瀏覽器的渲染引擎 渲染流程 渲染樹與渲染物件 迴流 全域性佈局和增量佈局 "迴流"還是"重排"?