《高性能javascript》 領悟随筆之-------DOM程式設計篇二
序:在javaSctipt中,ECMASCRIPT規定了它的文法,BOM實作了頁面與浏覽器的互動,而DOM則承載着整個頁面文檔。DOM程式設計性能一直以來都是非常受開發者關注的話題,如何編寫高性能的DOM是前端開發必不可少的技能。
1.重繪與重排
當浏覽器加載完頁面所有的元素、js、css、圖檔之後會自動生成兩個資料結構:
1.dom樹

(圖檔為轉載)
如圖所示,dom樹表示了整個頁面文檔的結構,通過通路dom樹我們可以得到某個元素,并且操作這個元素;
2.渲染樹
表示dom節點如何顯示;
《高性能javascript》一書中是這麼描述的:dom樹中每一個需要顯示的節點在渲染樹中至少存在一個對應的節點(隐藏的dom元素在渲染樹中沒有對應的節點)。渲染樹中的節點被稱為 “幀(frams)” 或 “盒(boxes)”,符合css模型的定義,了解頁面元素為一個具有内邊距(padding),外邊距(margins),邊框(borders)和位置(position)的盒子。一旦dom和渲染樹建構完成,浏覽器就開始顯示頁面元素。
參考 http://blog.csdn.net/greenqingqingws/article/details/19822139 詳細闡述了
【浏覽器渲染原理】渲染樹建構之渲染樹和DOM樹的關系;當我們去修改元素的屬性,比如寬度、高度、動态增加文字、就會引起浏覽器的“重排 與 重繪”,減少它發生的次數是提高dom性能的關鍵之一;
那麼如何減少 “重排 與 重繪” 發生的次數呢?
3.合并多次對dom和樣式的修改,然後一次性處理掉;
一個栗子:
var el = document.getElementById('mydiv');
el.style.color='red';
el.style.padding='5px';
el.style.borderLeft = "1px solid red";
這個栗子中div有三個元素樣式的改變,每一個都會影響元素的結構,這種情況會導緻在某些浏覽器下頁面觸發三次重排,這麼做效率是非常低下的;
将css集中修改:csstext 方法,它可以以字元串的形式一次性修改css樣式資訊,需要注意的是它會覆寫已存在的行間樣式資訊;
var el = document.getElementById('mydiv');
var csstext = "color:red;border-right:1px solid red;padding:5px;";
//集中一次性修改樣式
el.style.cssText += csstext;
還可以使用添加删除class名稱達到同樣的效果,通過class名得到的性能會更好,在不同的應用場景應首先考慮增删class名的修改方法;
4.批量修改dom;
當我們通過ajax請求得到一個清單資料的時候,我們需要循環将資料插入到頁面中。如果每次循環插入一個節點的話,那頁面很可能會直接崩潰掉,我們要避免這個問題的發生;
文檔片段(document.createDocumentFragment());
建立一個隐式的副本,看栗子
//建立一個fragment臨時dom存儲空間
var fragment= document.createDocumentFragment();
for(......){
var div = document.createElement("div");
........
//将div存儲在fragment臨時空間中
fragment.appendChild(div);
}
//将組裝好的dom塞進body
document.body.appendChild(fragment);
此方法隻插入一次,完成所有的dom更新工作,是dom操作性能的關鍵之一 (innerHTML同理)
2.事件委托
每多綁定一個事件處理程式都會加重頁面的性能負擔,簡單優雅的操作應該使用 “事件委托”。 它基于事件冒泡機制;通過監聽父級元素的事件,判斷出事件的來源元素;
當我們點選div,div觸發click事件,事件被冒泡到body body觸發click事件直到文檔根document;
假如要給頁面中的每一個a元素添加一個點選事件,我們可以這樣做:
document.addEventListener("click",function(ev){
var Event = ev||window.event;
if(Event.target.nodeName=="A"){
alert("點選了a标簽");
}
},false);
當a點選被冒泡到document的時候,判斷它的來源,如果是a則執行相應的代碼,這就是事件委托的概念;
在jQuery中事件冒泡被封裝在.on()方法裡 , 可以更簡單的使用它:
$(document).on("click","a",function(){
alert("這是一個a标簽");
});
更多關于事件委托 參考:http://www.cnblogs.com/leejersey/p/3801452.html
js中的事件委托3.dom篇總結
1.最小化通路dom的次數,盡可能使用javascript處理;
2.如果多次通路一個dom節點,需要儲存局部變量中;
3.處理html集合最好的方法是将他們複制到一個臨時的數組中,數組的通路速度要比dom快的多;
4.使用事件委托
--------------學無止境,站在巨人的肩上才能看的更高、更遠--------------
========================================================
轉載請注明出處。