您的位置:首页 > 其它

关于DOM操作的性能优化

2014-11-13 12:55 239 查看
最著名的有关用js操作dom的观点是:js和dom是独立的小岛,用桥实现两者的联系,但桥很窄,要过路费,所以我们要尽最大可能减少过桥的次数。下面代码演示了用js操作dom的innerHTML,且一下修改5000次:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>testcss</title>
<style>

</style>
<script type="text/javascript">
window.onload=function(){

var odiv=document.getElementById('d1');
var str='';

console.time('hello');//用于后台计时
for(var i=0;i<5000;i++)
{
odiv.innerHTML+='a';   //不停的延长innerHTML,5000次
}
console.timeEnd('hello');//用于后台计时

}
</script>
</head>
<body>
<div id='d1'>dddd</div>
</body>
</html>
以上代码运行起来是十分消耗性能的,虽然各浏览器处理时间不一样,但很明显,都很吃力。以下是谷歌和火狐浏览器的处理时间:

谷歌:



火狐:



很明显火狐在处理这种操作方面明显优于谷歌。

上述代码用了最笨的方式,‘过桥’的次数也达到5000次,可以说是最笨的方式了。那倒不如,先把这5000次的处理都放在js这座岛上,5000次处理完后直接把结果一次性交给dom,也就只过桥一次:

var str=''; 
console.time('hello');
for(var i=0;i<5000;i++)
{
str+='a';    //5000次后得到结果str(5000个a)

}
odiv.innerHTML+='a';  //一次性交给dom,只过桥一次
console.timeEnd('hello');
以上是改进代码,极大极大的节省了性能:

谷歌:



火狐:



这样改进后提升的性能不是简简单单的几倍,而是上千倍。当然了一下处理5000次在工作中几乎碰不到,但这种方法值得留意。

还有一些提高性能的技巧:

在选择dom节点时尽可能使用querySelector() ,querySelectorAll() (IE8以下不支持)

还有在插入节点时应先设置好innerHTML再最后一步用appendChild()插入,能提高性能,(上篇代码的注释中提到),如果在节点已经插入后再设置其innerHTML又会多了一步浏览器的重排和重绘。关于重绘和重排请看我的这篇文章另一篇文章

利用cssText:在改变dom的css样式时,如果要改变多个css属性,尽量少用 节点.style.XX='XXX';而是用 节点.style.cssText='width:200px; height:200px; background:red;' 这种方式。

缓存布局信息:把浏览器每次都要获取的信息保存为一变量,用 这个变量进行累加,那么浏览器就不用每次都获取。

少用字符串拼接,因为字符串拼接的原理要比你想象中的“费劲”,例如:var str='tom'; str=str+'cat'; 最终结果str=“tomcat”。看似轻松,但对浏览器来说其处理字符串拼接过程是先创建一个长度为6的字符串(tomcat的长度为6),然后先往里填充tom,再往里填充cat,最后一步把之前的str=‘tom’ 销毁掉。这样就生成了新的字符串,而不是想象中的只是在str=‘tom’后面直接追加cat那么简单。虽然新版本浏览器性能够强悍,但作为前端我们接触最多的就是浏览器,所以我们要爱她,呵护她。(注意是“她”哦)

大量创建元素节点时使用createDocumentFragment();

等,关于性能提高笔记上还有很多很多这里推荐雅虎性能优化军规,不再一一叙述。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: