优化你的DOM

优化DOM的实质实在就是削减DOM树的重流与重绘。关于重流和重绘的明白,详见《前端学问提高之HTML
优化DOM的构造,不过就是援用保留,动画优化,节点保留,更新节点等基础操纵。
曾记得,之前在网上翻阅HTML的时刻,很多人都邑不谋而合(儿童)的说道,获取到DOM节点后一定要记得保留。不然,下场很丢脸的。
为何~为何~为何~
我们都晓得所谓的js实际上是DOM,BOM,ECMA连系的产品。 原本我js挺快的,你非要去的DOM说说话。 那怎么办,只需敲拍门,等DOM来回应你呀~ 然则,这个等待时候灰常长。
看个demo吧.

var times=10000;
var time1 = function(){
   var time = times;
  while(time--){  //DOM的两个操纵放在轮回内
      var dom = document.querySelector("#Div1");
      dom.innerHTML+="a";
  }
};
var time2=function(){
    var time = times,
    dom = document.querySelector("#Div1");
  while(time--){ //DOM的一个操纵放在轮回内
     dom.innerHTML+="a";
  }
};
var time3=function(){
    var time = times,
    dom = document.querySelector("#Div1"),
    str = "";
  while(time--){ //轮回内不安排DOM的操纵
    str +="a";
  }
  dom.innerHTML=str;
}
console.time(1);  //设置时候出发点
time1();
console.timeEnd(1);
console.time(2);  //设置时候出发点
time2();
console.timeEnd(2);
console.time(3);  //设置时候出发点
time3();
console.timeEnd(3);

//测试效果为:
1: 101.868ms
2: 101.560ms
3: 13.615ms

固然,这只是个比较夸大的例子了,当你过量的频仍操纵DOM的时刻,一定要记得保留。 而且,保留一定是要保留一切触及DOM相干的操纵。
比方. style,innerHTML等属性。
而如许做的道理就是削减重流和重绘的次数。

重流重绘发作的状况

那重流和重绘一般什么状况下会发作呢?
重流发作状况:

  1. 增加或许删除可见的DOM元素

  2. 元素位置转变

  3. 元素尺寸转变

  4. 元素内容转变(比方:一个文本被另一个差别尺寸的图片替换)

  5. 页面衬着初始化(这个没法防备)

  6. 浏览器窗口尺寸转变

总的来说,就是转变页面的规划,大小,都邑发作重流的状况。
那重绘什么时刻会发作呢? 发作重流就一定会发作重绘,然则,重绘的局限比重流轻微大了一点。比方,当你仅仅转变字体色彩,页面背景色彩等 比较”浅薄”的操纵时,是不会打扰到重排的。

兼并DOM的操纵

当我们如许操纵时:

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

浏览器会很智慧的将两次重排兼并到一次发作,节约资本。 实在函数撙节的头脑和这个有殊途同归的妙处

var throttle = (function(){
    var time;
    return function(fn,context){  
        clearTimeout(time);  //举行函数的撙节
        time = setTimeout(fn.bind(context),200);
    }
})()

这个技能一般用在你调解浏览器大小的时刻。
然则,假如中心,你访问了offsetTop,clientTop等 马上实行属性的话。那效果你就么么哒了。

div.style.color="red";  //积聚一次重排纪录
var height = div.clientHeight;  //触发重排
div.style.border="1px solid red";  //再次积聚一次重排

这时刻,浏览器已被你玩傻了。 所以,给的一点发起就是,假如要变动DOM构造最好一次性整完,或许,要整一起整~
我们上面的css修正,还能够如许

div.style.cssText="color:red;border:1px solid red"; //掩盖本来的css
div.classList.add("change"); //应用class来团体修改

DOM操纵的优化

DOM的操纵不过就CRUD。
这里简单说一下基础的API

建立节点

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

查找节点

var divs = document.querySelectorAll('div'); //很多个,放在数组内
var onlydiv = document.querySelector('div'); //只需一个
//以及document.getElement系列

检察节点

var html = div.innerHTML; 
var outer = div.outerHTML;  //这两个黑白常经常运用的
var classNames = div.classList;
var className = div.className;
var tagName = div.tagName;
var id = div.id;
var style = div.getAttribute("style");
//....

挪动节点

ele.replaceChild(replace,replaced); //replace替代replaced
//增加子节点
ele.appendChild(child);
//删除子节点
ele.removeChild(child);
//插进去子节点
ele.insertBefore(newEle,referenceEle);

Ok~ 实在,上面所说的这些API只需触及到DOM操纵的都邑发作重排。所以,这里是处所能够优化的.

运用fragment

当我们须要批量到场子节点的时刻,就须要运用fragment这个假造片段,来作为一个容器.
比方,我们须要在div内里增加100个p标签

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.352ms
2: 0.685ms

除了运用fragment片段,还能够运用innerHTML,outerHTML举行相干的优化操纵。这里就不赘述了

UI操纵的优化

这里想说的实在不多,就是学会运用absolute排版。 由于当你举行相干UI操纵的时刻,毫无疑问有能够不经意间,致使全屏的衬着。比方校园二手街的规划,当你下滑的时刻,他的headerbar便会发作扩展,规划较差的状况是整版重排。(傻逼傻逼傻逼)
他这里不一样,他直接运用absolute举行规划,脱离了文档流,防备页面过分的重排,赞~
末了:
优化之路漫漫,人人好自为之~

    原文作者:villainhr
    原文地址: https://segmentfault.com/a/1190000004451493
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞