DOM優(yōu)化

優(yōu)化DOM的本質(zhì)其實(shí)就是減少DOM樹的重流與重繪。
優(yōu)化DOM的結(jié)構(gòu),無非就是引用保存,動畫優(yōu)化,節(jié)點(diǎn)保存,更新節(jié)點(diǎn)等基本操作。
獲取到DOM節(jié)點(diǎn)后一定要記得保存。否則,下場很難看的。
為什么
我們都知道所謂的js其實(shí)是DOM,BOM,ECMA結(jié)合的產(chǎn)物。 本來我js挺快的,你非要去的DOM說說話。 那怎么辦,只有敲敲門,等DOM來回應(yīng)你呀~ 但是,這個(gè)等待時(shí)間灰常長。
看個(gè)demo吧.

創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站制作、成都做網(wǎng)站、原陽網(wǎng)絡(luò)推廣、小程序開發(fā)、原陽網(wǎng)絡(luò)營銷、原陽企業(yè)策劃、原陽品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供原陽建站搭建服務(wù),24小時(shí)服務(wù)熱線:13518219792,官方網(wǎng)址:muchs.cn

var times=10000;var time1 = function(){   var time = times;  while(time--){  //DOM的兩個(gè)操作放在循環(huán)內(nèi)
      var dom = document.querySelector("#Div1");
      dom.innerHTML+="a";
  }
};var time2=function(){    var time = times,
    dom = document.querySelector("#Div1");  while(time--){ //DOM的一個(gè)操作放在循環(huán)內(nèi)
     dom.innerHTML+="a";
  }
};var time3=function(){    var time = times,
    dom = document.querySelector("#Div1"),
    str = "";  while(time--){ //循環(huán)內(nèi)不放置DOM的操作
    str +="a";
  }
  dom.innerHTML=str;
}console.time(1);  //設(shè)置時(shí)間起點(diǎn)time1();console.timeEnd(1);console.time(2);  //設(shè)置時(shí)間起點(diǎn)time2();console.timeEnd(2);console.time(3);  //設(shè)置時(shí)間起點(diǎn)time3();console.timeEnd(3);//測試結(jié)果為:1: 101.868ms2: 101.560ms3: 13.615ms

當(dāng)然,這只是個(gè)比較夸張的例子了,當(dāng)你過多的頻繁操作DOM的時(shí)候,一定要記得保存。 而且,保存一定是要保存所有涉及DOM相關(guān)的操作。
比如. style,innerHTML等屬性。
而這樣做的原理就是減少重流和重繪的次數(shù)。

重流重繪發(fā)生的情況

那重流和重繪通常什么情況下會發(fā)生呢?
重流發(fā)生情況:

  1. 添加或者刪除可見的DOM元素

  2. 元素位置改變

  3. 元素尺寸改變

  4. 元素內(nèi)容改變(例如:一個(gè)文本被另一個(gè)不同尺寸的圖片替代)

  5. 頁面渲染初始化(這個(gè)無法避免)

  6. 瀏覽器窗口尺寸改變

總的來說,就是改變頁面的布局,大小,都會發(fā)生重流的情況。
那重繪什么時(shí)候會發(fā)生呢? 發(fā)生重流就一定會發(fā)生重繪,但是,重繪的范圍比重流稍微大了一點(diǎn)。比如,當(dāng)你僅僅改變字體顏色,頁面背景顏色等 比較"膚淺"的操作時(shí),是不會打擾到重排的。

合并DOM的操作

當(dāng)我們這樣操作時(shí):

div.style.color="red";
div.style.border="1px solid red";

瀏覽器會很聰明的將兩次重排合并到一次發(fā)生,節(jié)省資源。 其實(shí)函數(shù)節(jié)流的思想和這個(gè)有異曲同工的妙處

var throttle = (function(){
    var time;
    return function(fn,context){  
        clearTimeout(time);  //進(jìn)行函數(shù)的節(jié)流
        time = setTimeout(fn.bind(context),200);
    }
})()

這個(gè)技巧通常用在你調(diào)整瀏覽器大小的時(shí)候。
但是,如果中間,你訪問了offsetTop,clientTop等 立即執(zhí)行屬性的話。那結(jié)果你就么么噠了。

div.style.color="red";  //積累一次重排記錄var height = div.clientHeight;  //觸發(fā)重排div.style.border="1px solid red";  //再次積累一次重排

這時(shí)候,瀏覽器已經(jīng)被你玩傻了。 所以,給的一點(diǎn)建議就是,如果要更改DOM結(jié)構(gòu)最好一次性整完,或者,要整一起整~
我們上面的css修改,還可以這樣

div.style.cssText="color:red;border:1px solid red"; //覆蓋原來的cssdiv.classList.add("change"); //利用class來整體改動

DOM操作的優(yōu)化

DOM的操作無非就CRUD。
這里簡單說一下基本的API

創(chuàng)建節(jié)點(diǎn)

var div = document.createELement("div");

查找節(jié)點(diǎn)

var divs = document.querySelectorAll('div'); //很多個(gè),放在數(shù)組內(nèi)var onlydiv = document.querySelector('div'); //只有一個(gè)//以及document.getElement系列

查看節(jié)點(diǎn)

var html = div.innerHTML; 
var outer = div.outerHTML;  //這兩個(gè)是非常常用的var classNames = div.classList;var className = div.className;var tagName = div.tagName;var id = div.id;var style = div.getAttribute("style");
//....

移動節(jié)點(diǎn)

ele.replaceChild(replace,replaced); //replace代替replaced//添加子節(jié)點(diǎn)ele.appendChild(child);//刪除子節(jié)點(diǎn)ele.removeChild(child);//插入子節(jié)點(diǎn)ele.insertBefore(newEle,referenceEle);

Ok~ 其實(shí),上面所說的這些API只要涉及到DOM操作的都會發(fā)生重排。所以,這里是地方可以優(yōu)化的.

使用fragment

當(dāng)我們需要批量加入子節(jié)點(diǎn)的時(shí)候,就需要使用fragment這個(gè)虛擬片斷,來作為一個(gè)容器.
比如,我們需要在div里面添加100個(gè)p標(biāo)簽

var times = 100;var addP = function(){    var time = times,
    tag1 = document.querySelector('#tag1');    while (time--) {        var p = document.createElement('p');
        tag1.appendChild(p);
    }
}var useFrag = function(){    var time = times,
    tag1 = document.querySelector('#tag1'),
    frag = document.createDocumentFragment();    while (time--) {        var p = document.createElement('p');
        frag.appendChild(p);
    }
    tag1.appendChild(frag);
}console.time(1);
addP();console.timeEnd(1);console.time(2);
useFrag();console.timeEnd(2);//基本事件差為:1: 1.352ms2: 0.685ms

除了使用fragment片斷,還可以使用innerHTML,outerHTML進(jìn)行相關(guān)的優(yōu)化操作。

UI操作的優(yōu)化

這里想說的其實(shí)不多,就是學(xué)會使用absolute排版。 因?yàn)楫?dāng)你進(jìn)行相關(guān)UI操作的時(shí)候,毫無疑問有可能不經(jīng)意間,導(dǎo)致全屏的渲染。
他這里不一樣,他直接使用absolute進(jìn)行布局,脫離了文檔流,防止頁面過度的重排,贊~

網(wǎng)頁題目:DOM優(yōu)化
URL分享:http://muchs.cn/article26/gcesjg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設(shè)計(jì)公司、動態(tài)網(wǎng)站、網(wǎng)站策劃、軟件開發(fā)、域名注冊、響應(yīng)式網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)