很多人讨论js一些算法和使用习惯对执行效率的影响。
但是本人认为随着浏览器的优化,单纯js代码本身的优化对这个应用的影响微不足道(因为我们的js代码一般构不成一定的数量级,但是对字符串的操作是一个特例),更多的要考虑的应该是资源文件的大小和对dom操作的优化上。
比起资源下载的耗时和dom的耗时,js执行时间是微乎其微,可优化的空间的很小,js的结构应该是以可读性和可维护行为先,如果为了百分之一秒不到的时间,牺牲了可读性就得不偿失了。
dom操作篇
dom最常见的操作就是创建、添加、查找、和修改(删除)元素,下面就来比较几种添加方式的效率。
先举个例子:
for(var i=0; i<1000; i++){
var p = document.createElement("p");
document.body.appendChild(p);
}
在ie9下的执行结果20ms,在ff下的执行结果93ms,这难道就是传说中的ie9的神速吗?
不急,接着往下看,把它稍加改造。
for(var i=0; i<1000; i++){
var p = document.createElement("p");
p.innerHTML = "this is p";
document.body.appendChild(p);
}
运行结果 ie9 153ms,ff 135ms。
原来页面只append空的p,ie是不进行渲染的,因此是“神速的”。
append一个堆空元素,对我们来说意义不大,下面的例子更符合实际,让我们开始优化之旅。
我还在此实验了把document和body的局部化,但是提升很小,也证明了我开始说明的问题。
优化1,使用DocumentFragment
var fm = document.createDocumentFragment();
for(var i=0; i<1000; i++){
var p = document.createElement("p");
p.innerHTML = "this is p<br>this is p";
//p.innerHTML += "<br>this is p";
fm.appendChild(p);
}
document.body.appendChild(fm);
运行结果 ie9 159ms,ff 94ms。
可以看出在ie下并没有减少,但是在ff下的效果还是明显的,因为我们每append一个元素到dom中,页面都会进行一次重绘,而使用 DocumentFragment,我们先将元素都添加到一个临时的dom结构片段中,此时页面并没有变化节约了重绘的时间,然后将整个fragment 一次插入dom中,整个过程只进行了一下重绘。
如果我们要添加的结构只有一个跟节点,可以用这个根节点代替DocumentFragment,直接把所有子节点append到根节点最后后把根节点插入到dom结构中。
如:var rootEl = document.createElement("div");
...
document.body.appendChild(rootEl);
在ff中时间可以减少到43ms
优化2,使用innerHTML
如果不是必需使用到每个节点的引用,我们可以用innerHTML让浏览器自己解析文档结构。
var rootDiv = document.createElement("div");
var html = "";
for(var i=0; i<1000; i++){
html += "<p>this is p<br>this is p</p>";
}
rootDiv.innerHTML = html;
document.body.appendChild(rootDiv);
运行结果 ie9 21ms,ff 16ms。
果然时间减少了很多,ie9一直居高不下的时间也一下回到了解放前,看来这才是对ie9浏览器的杀手锏。
我对此优化的推断是,直接赋值innerhHTML最大的减少了js引擎和浏览器渲染引擎之间的交互,看来js引擎和浏览器渲染引擎的交互次数才是最大的杀手。
此处还可以用数组来操作字符串的拼接。
var rootDiv = document.createElement("div");
var html = [];
for(var i=0; i<1000; i++){
html.push("<p>this is p<br>this is p</p>");
}
rootDiv.innerHTML = html.join('');
document.body.appendChild(rootDiv);
ie9的平均时间可以达到17ms,ff没有什么变化,据说部分浏览器在字符串拼接上已经进行了优化,也许ff已经优化过来。
同时也反映了我开始的观点,js本身的操作对性能的影响是很小的。
总结一下dom方面的优化就是,尽量减少页面的重绘次数和js与dom的交互次数。
web前端优化之dom篇
最新推荐文章于 2024-08-30 11:12:09 发布