高效能javascript讀書筆記之操作DOM
阿新 • • 發佈:2019-01-02
DOM:文件物件模型,是一個獨立於語言的,用來操作XML和HTML文件的程式介面(API)。
瀏覽器通常會把DOM和javascript獨立實現,每次連線DOM和ECMAScript,都會被收取“過橋費”(效能消耗)。
優化方法:
1.減少訪問DOM的次數,把運算儘量留在ECMAScript這一端處理。
慢:
function innerHTMLLoop() {
for(var count=0;count<15000;count++) {
document.getElementById(‘here’).innerHTML += ‘a';
}
}
改進: 用區域性變數儲存修改中的內容,在迴圈結束後一次性寫入。
function innerHTMLLoop2() {
var content =‘';
for(var count=0;count<15000;count++) {
content += ‘a';
}
document.getElementById(‘here’).innerHTML += content;
}
2.如果需要多次訪問某個DOM節點,請使用區域性變數儲存它的引用。
3.innerHTML屬性和類似 document.createElement的原生DOM方法比較:在除開最新版的Webkit核心(Chrome和Safari)之外的所有瀏覽器中,innerHTML會更快一些。
4.節點克隆:使用element.cloneNode()先建立需要重複的元素,然後重複拷貝操作,但改善不是很明顯。
5.小心處理HTML集合,它實時連繫著底層文件。把集合的長度快取到一個變數中,並在迭代中使用它。如果需要經常操作集合,建議把它拷貝到一個數組中。
HTML集合是包含了DOM節點引用的類陣列物件,並不是真正的陣列(沒有push(),slice()等方法),但是有length屬性也能以數字索引的方式訪問列表元素。
如:document.getElementsByTagName()等
把集合的長度快取到一個變數中,並在迭代中使用它。
function loopCacheLengthCollection() {
var coll = document.getElementsByTagName(‘div');
var len = coll.length;
for (var i=0;i<len;i++) {
/*程式碼處理*/
}
}
當遍歷一個集合時,第一優先原則是把集合儲存在區域性變數中,並把length快取在迴圈外部,然後,使用區域性變數替代這些需要多次讀取的元素。
function collectionNodesLocal() {
var coll = document.getElementsByTagName(‘div’),
len = coll.length,
name = ‘',
el = null;
for (var i=0;i<len;i++) {
el = coll[i];
name = el.nodeName;
name = el.nodeType;
name = el.tagName;
}
return name;
}
6.如果可以的話,選擇速度更快的API。
某些情況下,需要只訪問元素節點:
屬性名 被替代的屬性
children childNodes
childElementCount childNodes.length
firstElementChild firstChild
lastElementChild lastChild
nextElementSibling nextSibling
previousElementSibling previousSibling
注:IE6,7,8只支援children屬性。children屬性不包含空白節點。
使用選擇器API,如:querySelectorAll() 和querySelector()
注:IE8,Firefox3.5,Safari3.1,Chrome1,Opera10以上支援。
7.留意重繪和重排,批量修改樣式時,“離線”操作DOM樹,使用快取,並減少訪問佈局資訊的次數。
重排(reflow):當DOM的變化影響了元素的幾何屬性(寬、高),瀏覽器需要重新計算元素的幾何屬性,同樣其它元素的幾何屬性也會受到影響,瀏覽器會使渲染樹中受影響的部分失效,並重新構造渲染樹。
重繪(repaint):完成重排後,瀏覽器會重新繪製受影響的部分到螢幕中。
減少重繪、重排次數:
合併所有修改,然後一次處理掉(cssText屬性、修改CSS的class名稱);
使元素脫離文件流-對其應用多重改變-把元素帶回文件流中(display屬性、文件片段document.createDocumentFragment()-推薦、為需要的節點建立備份,對副本進行操作);
動畫中使用絕對定位;
8.使用事件委託來減少事件處理器的數量。