JavaScript优化-DOM
发布日期:2021-05-06 19:35:30 浏览次数:25 分类:技术文章

本文共 5397 字,大约阅读时间需要 17 分钟。

1. 什么是DOM

  • 用于操作XML和HTML文档的应用程序
    • DOM节点(ul,li)
    • DOM树(DOM节点的整体)
    • DOM API
      • getElementById
      • childNodes
      • appendChild
      • innerHTML

2. Dom与JavaScript

1)概念

- 浏览器会把dom与js独立实现
- 像两个独立的小岛
- js操作 dom
- 从一个岛到另一个岛
- dom的性能
- 岛与岛之间的桥,每次通过收取“过桥费”
- 尽量减少过桥的次数
- innerHTML与dom方法对比

2)举例

以下代码运行时间为600ms左右

window.onload=function(){    var oDiv=document.getElementById('div1');    console.time('hello');    for(var i=0;i<5000;i++){     oDiv.innerHTML+='a';    }    console.timeEnd('hello');}

以下代码运行时间为1ms左右,定义一个变量str

window.onload=function(){    var oDiv=document.getElementById('div1');    var str='';    console.time('hello');    for(var i=0;i<5000;i++){     str+='a';    }    oDiv.innerHTML=str;    console.timeEnd('hello');}

3)关于innerHTML与dom方法对比

以下使用DOM方法操作,时间为350ms左右

window.onload=function(){    var oUl=document.getElementById('ul1');    console.time('hello');    for(var i=0;i<5000;i++){     var oLi=document.createElement('li');     oUl.appendChild(oLi);    }    console.timeEnd('hello');}

以下使用innerHTML方法操作,时间为290ms左右

window.onload=function(){    var oUl=document.getElementById('ul1');    var str='';    console.time('hello');    for(var i=0;i<5000;i++){      str += '
  • '; } oUl.innerHTML=str; console.timeEnd('hello');}

    注意:以上是在火狐中,但是在Chrome浏览器中,上面为10ms,下面为44ms

    chrome:dom方法要比innerHTML性能要好。

    3. 减少DOM操作

    • 节点克隆
      • cloneNode
    • 访问元素集合
      • 尽量用局部变量
    • 元素节点
      • 尽量用只获取元素的节点方法
    • 选择器API
      • 利用querySelector,querySelectorAll

    1)节点克隆

    运行时间440ms左右

    window.onload=function(){    var oUl=document.getElementById('ul1');    console.time('hello');    for(var i=0;i<5000;i++){     var oLi=document.createElement('li');     oLi.innerHTML='li';     oUl.appendChild(oLi);    }    console.timeEnd('hello');}

    使用节点克隆,运行时间为360ms

    window.onload=function(){    var oUl=document.getElementById('ul1');    console.time('hello');    var oLi=document.createElement('li');    oLi.innerHTML='li';    for(var i=0;i<5000;i++){     var newLi=oLi.cloneNode(true);     oUl.appendChild(newLi);    }    console.timeEnd('hello');}

    2)访问元素集合

    460ms

    window.onload=function(){
    var oUl=document.getElementById('ul1'); var aLi=oUl.getElementsByTagName('li'); for(var i=0;i<5000;i++){ var oLi=document.createElement('li'); oUl.appendChild(oLi); } console.time('hello'); for(var i=0;i

    用局部变量,450ms

    window.onload=function(){    var oUl=document.getElementById('ul1');    var aLi=oUl.getElementsByTagName('li');    for(var i=0;i<5000;i++){     var oLi=document.createElement('li');     oUl.appendChild(oLi);    }    console.time('hello');    var len=aLi.length;    for(var i=0;i

    在其他方面的应用

    var oDiv=document.getElementById('div');var oUl=document.getElementById('ul');换成下面这种方式性能会提高很多var doc=document;var oDiv=doc.getElementById('div');var oUl=doc.getElementById('ul');

    3)元素节点(尽量用只获取元素的节点方法)

    childNodes ->元素节点、文本节点

    children ->元素节点
    firstChils
    firstElementChild

    4)选择器API

    var oUl=document.getElementById('ul1');var aLi=oUl.getElementsByTagName('li');

    可以这样写

    var aLi=document.querySelectorAll('#UL1 li');

    4. Dom与浏览器

    • 重排:改变页面的内容
    • 重绘:浏览器显示内容
    • 添加顺序
      • 尽量在appendChild前添加操作
    • 合并dom操作
      • 利用cssText
    • 缓存布局信息
    • 文档碎片
      • createDocumentFragment()
    • Dom与事件
      • 事件委托
    • Dom与前端模板
      • 能更好的对逻辑和视图分离,MVC架构的基础

    1)添加顺序( 尽量在appendChild前添加操作)

    750ms

    window.onload=function(){    var oUl=document.getElementById('ul1');    console.time('hello');    for(var i=0;i<5000;i++){     var oLi=document.createElement('li');     oUl.appendChild(oLi);     oLi.innerHTML='li';    }    console.timeEnd('hello');}

    450ms。不会进行重排重绘的过程。

    window.onload=function(){    var oUl=document.getElementById('ul1');    console.time('hello');    for(var i=0;i<5000;i++){         var oLi=document.createElement('li');         oLi.innerHTML='li';//调换顺序         oUl.appendChild(oLi);    }    console.timeEnd('hello');}

    2)合并dom操作(利用cssText)

    500ms

    window.onload=function(){    var oUl=document.getElementById('ul1');    console.time('hello');    for(var i=0;i<5000;i++){         var oLi=document.createElement('li');         oLi.style.width='100px';         oLi.style.height='100px';         oLi.style.background='red';         oUl.appendChild(oLi);    }    console.timeEnd('hello');}

    490ms

    window.onload=function(){    var oUl=document.getElementById('ul1');    console.time('hello');    for(var i=0;i<5000;i++){         var oLi=document.createElement('li');         oLi.style.cssText='width:100px;height:100px;background:red;';         oUl.appendChild(oLi);    }    console.timeEnd('hello');}

    3)缓存布局信息

    //div1是一个红色的100px的正方块window.onload=function(){
    var oDiv=document.getElementById('div1'); setInterval(function(){
    oDiv.style.left=oDiv.offsetLeft+1+'px'; oDiv.style.top=oDiv.offsetTop+1+'px'; },30);};

    如何利用缓存布局信息

    //div1是一个红色的100px的正方块window.onload=function(){
    var oDiv=document.getElementById('div1'); var L=oDiv.offsetLeft; var T=oDiv.offsetTop; setInterval(function(){
    L++;T++; oDiv.style.left=L+'px'; oDiv.style.top=T+'px'; },30);};

    4)文档碎片(createDocumentFragment())

    360ms

    window.onload=function(){    var oUl=document.getElementById('ul1');    console.time('hello');    for(var i=0;i<5000;i++){         var oLi=document.createElement('li');         oUl.appendChild(oLi);    }    console.timeEnd('hello');}

    300ms

    window.onload=function(){    var oUl=document.getElementById('ul1');    var oFrag=document.createDocumentFragment();    console.time('hello');      for(var i=0;i<5000;i++){         var oLi=document.createElement('li');         oFrag.appendChild(oLi);    }     oUl.appendChild(oFrag);    console.timeEnd('hello');}
    上一篇:关于json
    下一篇:对象引用

    发表评论

    最新留言

    感谢大佬
    [***.8.128.20]2025年04月04日 05时08分49秒