Web 技术研究所

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

Chrome上插入元素的性能优化

  Chrome的渲染引擎是存在BUG的,这导致插入元素时需要的时间是指数增长的。在前两篇文章中已经做了很多测试,但那些都是比较慢的方法。其实使用innerHTML就可以让性能提高很多,但是innerHTML操作的毕竟是HTML文本,而且这个方法使用起来并不方便。
<style>
span {
  display:inline-block;border:1px solid #CCC;
  margin:3px;padding:3px;font-family:Consolas;
}
</style>
<script>
onload=function(){
  var i,e,s=[],t=new Date;
  for(i=0;i<1E4;i++)s.push("<span>"+i+"</span>");
  document.body.innerHTML=s.join("");
  setTimeout(function(){
    console.log(new Date-t);
  });
};
</script>
  比其之前的慢方法,这个的效率已经不错了吧?但是innerHTML的问题是只能输入字符串,如果要为每个元素做一些特殊的操作就麻烦了,HTML并不是万能的。而且innerHTML还会覆盖原来的数据,这个方法如果想用在已有数据的地方添加数据就必须嵌套个容器,这是毁逻辑的事情。所以innerHTML的方法并不太实用。
  其实innerHTML的效率还不是最高的,它同样被渲染引擎的BUG坑了,仍然是指数的时间复杂度。只是不需要处理其它事情,所以使用上感觉它的效率比较高。这样解决治标不治本,把上面的数量级换到1E5的话innerHTML就要跪了。实际上,Chrome的问题出在同一个消息中添加大量元素时渲染会出问题,我们只要不在同一个消息中添加大量元素,把动作细分到多个消息中分别添加少量元素,这样时间复杂度就会降下了。虽然不及Firefox和IE,但比起自己的其它方法已经好很多了。
<style>
span {
  display:inline-block;border:1px solid #CCC;
  margin:3px;padding:3px;font-family:Consolas;
}
</style>
<script>
onload=function(){
  var body=document.body,count=100,t=new Date;
  (function callee(){
    for(var i=0,e;i<1E3;i++){
      e=document.createElement("span");
      e.textContent=(100-count)*1E3+i;
      body.appendChild(e);
    };
    if(--count)setTimeout(callee);
    else setTimeout(function(){
      console.log(new Date-t);
    });
  })();
};
</script>
  这个测试是添加100次,每次添加1E3个元素,最终可以得到1E5个元素,测试的速度就比innerHTML快了许多。而且这里是使用createElement实现的,这样我们就可以得到每一个元素的句柄,如果还需要对元素做其它操作可以很容易地加上。
  最后,我希望Chrome对CSS引擎也下点功夫,要不然很可能会被IE赶上的。
网名:
34.203.213.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^