前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何更优地去创建DOM元素

如何更优地去创建DOM元素

作者头像
IMWeb前端团队
发布2019-12-03 17:32:04
2.1K1
发布2019-12-03 17:32:04
举报
文章被收录于专栏:IMWeb前端团队IMWeb前端团队

本文作者:IMWeb yuchenli 原文出处:IMWeb社区 未经同意,禁止转载

如何更优地去创建DOM元素

创建DOM元素是最为基本的DOM操作,这里先举个栗子

这里先使用createElement创建了10个li元素

代码语言:javascript
复制
var list = document.querySelector('.list'),
    num = 10,;

for (t = 0; t < num; t++) {
   var li = document.createElement('li');
   list.appendChild(li);
}

measurethat测试的结果是:

image
image

这里简单地通过createElement创建DOM是存在比较严重的性能问题的:

1、createElement本身就是不小的性能开支

2、 每次创建li元素都换插入到DOM中,会引起多次重排和重绘。

innerHTM

对面上面那种问题,可能就会想到通过innterHTML方式去创建DOM元素 这里先举个栗子:

代码语言:javascript
复制
var str = '';
for (t = 0; t < num; t++) {
    str += `<li><li>`;
}
list = str;

测试结果如下:

image
image

相比之前的createElement方式性能提升了很多,不过这种方式仍然存在弊端:不方便获取创建的li元素,你不得不要等它渲染完成时,再去获取它。

cloneNode

cloneNode是用于克隆节点的,相比直接调用createElement创建DOM元素而言,它所花费的开销会更小些,就好比:读书的时候,抄作业要比做作业的容易的多。

举个栗子:

代码语言:javascript
复制
var li = document.createElement('li');
for (t = 0; t < num; t++) {
   var cloneLi = li.cloneNode();
   list.appendChild(cloneLi);
}

测试结果:

image
image

从结果中看出,cloneNode虽然比createElement快,但是还是不。那么还有没有更快的方式去创建DOM元素呢?接下来先介绍一个东西DocumentFragment

DocumentFragment

DocumentFragment是示一个没有父级文件的最小文档对象。它被当做一个轻量版的 Document使用,用于存储已排好版的或尚未打理好格式的XML片段。最大的区别是因为DocumentFragment不是真实DOM树的一部分,它的变化不会引起DOM树的重新渲染的操作,且不会导致性能等问题。考虑这个因素,我们可以结合cloneNode和DocumentFragment在去创建DOM元素并插入到文档:

代码语言:javascript
复制
var fragment = document.createDocumentFragment();
var li = document.createElement('li');
for (t = 0; t < num; t++) {
   var cloneLi = li.cloneNode();
   fragment.appendChild(cloneLi);
}
list.appendChild(fragment);

优化cloneNode+fragment

我们完全没有必要按照上面的方式,通过100次循环去将li放入fragment,因为fragment自身是可以被克隆的。利用这种特性,可以将100次循环降低到10次循环,具体的代码如下:

代码语言:javascript
复制
function cloneMultiple (elem, times, deep) {
   var fragment = document.createDocumentFragment();
   fragment.appendChild(elem.cloneNode(deep));
   if (times <= 1) {
       return fragment;
   }

   var i = 1,
       rest = [];

   while((times % 2 === 0 || !!(rest[i] = 1 && --times)) && (times /= 2) && times >3 ) {
        i += 1;  
   }

   while ( times > 1 ) {
      fragment.appendChild(elem.cloneNode(deep));
      --times;
   }

    for ( ; i; --i ) {
      fragment.appendChild(fragment.cloneNode(true));   
      rest[i] && fragment.appendChild(elem.cloneNode(deep));
    }

   return fragment;
}

 var li = document.createElement('li');
 list.appendChild(cloneMultiple(li, num, true));

最终测试结果

测试样例

image
image
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-09-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 如何更优地去创建DOM元素
    • innerHTM
      • cloneNode
        • DocumentFragment
          • 优化cloneNode+fragment
            • 最终测试结果
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档