zoukankan      html  css  js  c++  java
  • 《高性能javascript》 领悟随笔之-------DOM编程篇(二)

    《高性能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.使用事件委托

    --------------学无止境,站在巨人的肩上才能看的更高、更远--------------

     

  • 相关阅读:
    oracle 常用SQL
    ActiveMQ持久化方式
    集中队列的模式
    EDA: Event-Driven Architecture事件驱动架构
    ActiveMQ消息队列介绍
    Nginx 用log_format设置日志格式
    log4j的ConversionPattern参数的格式含义
    真正的轻量级WebService框架——使用JAX-WS(JWS)发布WebService
    Java的注解机制——Spring自动装配的实现原理
    java interface 默认值
  • 原文地址:https://www.cnblogs.com/ztfjs/p/domeach2.html
Copyright © 2011-2022 走看看