Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

appendChild和insertBefore的性能差异

  如果只从DOM操作的性能上分析,appendChild和insertBefore这两个方法本身是没有太大差异的。但是insertBefore本身具有appendChild无法比拟的功能,它对插入元素的位置是可以选择的。因此它对页面可能造成的影响也更大,渲染的开销也可能更大。
  我们先来测试appendChild和insertBefore本身的操作性能 <div id="blackhole" style="display:none;"></div>
<input id="append" value="appendChild" type="button" />
<input id="insert" value="insertBefore" type="button" />
<script>
append.onclick=function(){
  blackhole.innerHTML="";
  var i,t=new Date;
  for(i=0;i<1E4;i++)
    blackhole.appendChild(document.createElement("span"));
  console.log(new Date-t);
};
insert.onclick=function(){
  blackhole.innerHTML="";
  var i,t=new Date;
  for(i=0;i<1E4;i++)
    blackhole.insertBefore(document.createElement("span"),null);
  console.log(new Date-t);
};
</script>
  这个测试基本没有什么差异,因为insertBefore的第二个参数为null,插入的也是末尾的位置。但如果让insertBefore插入其它位置就不同了。我的元素是流内布局,如果先前的元素改变了,就可能影响到后面的一系列元素。下面这个测试就可以很明显的观察出差异了。
<input id="append" value="appendChild" type="button" />
<input id="insert" value="insertBefore" type="button" />
<style>
span {
  display:inline-block;border:1px solid #CCC;
  margin:3px;padding:3px;font-family:Consolas;
}
</style>
<div id="blackhole"></div>
<script>
(function(){ //生成初始数据
  var i,s=[];
  for(i=0;i<1E4;i++)s.push(i);
  s=s.join("</span><span>");
  blackhole.innerHTML="<span>"+s+"</span>";
})();
append.onclick=function(){
  var e,t=new Date;
  e=document.createElement("span");
  e.textContent="append";
  blackhole.appendChild(e);
  setTimeout(function(){
    console.log(new Date-t);
  });
};
insert.onclick=function(){
  var e,t=new Date;
  e=document.createElement("span");
  e.textContent="prepend";
  blackhole.insertBefore(e,blackhole.firstChild);
  setTimeout(function(){
    console.log(new Date-t);
  });
};
</script>
  但是大家会觉得,这是CSS本身渲染机制的问题吧?和insertBefore没关系。但是某些CSS确实需要根据位置来计算元素的属性,如果元素的位置都变了,那CSS就需要重新计算。比如把上面测试中的CSS部分改成这样后再测试就能很明显的看出结果。
span:first-child,span:first-child~span {
  display:inline-block;border:1px solid #CCC;
  margin:3px;padding:3px;font-family:Consolas;
}
  当然,我的测试是比较夸张的,只要是个正常人就不会写出这么脑残变态非主流的CSS。但是这确实是个影响insertBefore的因素,这里也只是为了突出问题而这么写的。如果排除掉这些因素,insertBefore和appendChild是几乎没性能上的差异的。
  最后顺便说一下,在IE6上,文档加载完毕之前使用appendChild会出错,而使用insertBefore就不会出错。
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^