JS性能DOM优化
chrome canary可以看每行代码的运行时间
转载于:https://my.oschina.net/u/1050900/blog/665969
什么是DOM?
- 用于操作XML和HTML文档的应用程序
- Dom节点 2. Dom树 3.Dom API
DOM优化
- 浏览器会把js和dom独立实现,js每次操作dom,都会增加一次耗时,为了提高dom性能,就要尽可能减少js对dom的操作,
以下是两个测试
1 <script> 2 window.onload=function(){ 3 var div=document.getElementById('div'); 4 var str=''; 5 console.time('test1'); 6 for(var i=0;i<5000;i++){ 7 div.innerHTML+='a'; 8 } 9 console.timeEnd('test1');//FireFox下 测试时间152ms 10 11 console.time('test2'); 12 for(i=0;i<5000;i++){ 13 str+='a'; 14 } 15 div.innerHTML=str; 16 console.timeEnd('test2');//FireFox下 测试时间1.36ms 17 }; 18 </script> 19 </head> 20 <body> 21 <div id="div"></div> 22 </body>
可以明显看出,test2只操作了一次dom,性能提高了很多
- 减少DOM操作的方法:
- 使用节点克隆 node.cloneNode()代替创建新的重复节点
- 使用局部变量代替访问节点集合,例如
var doc=document; var div=doc.getElementById('div'); var input=doc.getElementById('input');
- 尽量用只获取元素节点的获取方式,例如 使用children代替childNodes firstElementChild代替firstChild
- 选择器API: 使用querySelectorAll(除IE8以下的浏览器都得到良好支持)
DOM与浏览器
- 重排:改变页面内容的过程
- 重绘:重排结束之后,浏览器显示内容的过程
可以通过以下的方式减少重排和重绘的过程,从而提升浏览器性能
- 尽量在appendChild()前面进行操作
1 for(var i=0;i<50000;i++){ 2 var li=document.createElement('li'); 3 //不推荐 4 ul.appendChild(li); 5 li.innerHTML='li'; 6 } 7 for(i=0;i<5000;i++){ 8 var li=document.createElement('li'); 9 //推荐 10 li.innerHTML='li'; 11 ul.appendChild(li); 12}
- 使用cssText合并dom操作
- 缓存布局信息. 例如:
1 window.onload = function(){ 2 var oDiv = document.getElementById('div1'); 3 var L = oDiv.offsetLeft; 4 var T = oDiv.offsetTop; 5 setInterval(function(){ 6 L++; 7 T++; 8 oDiv.style.left = L + 'px'; 9 oDiv.style.top = T + 'px'; 10 },30); 11 };
- 利用文档碎片
1 window.onload = function(){ 2 var oUl = document.getElementById('ul1'); 3 var oFrag = document.createDocumentFragment(); 4 for(var i=0;i<5000;i++){ 5 var oLi = document.createElement('li'); 6 oFrag.appendChild(oLi); 7 } 8 oUl.appendChild(oFrag); 9 };
DOM与事件
- 通过事件代理(事件委托)来提升浏览器性能
1 console.time('test1'); 2 for(i=0;i<oLi.length;i++){ 3 oLi[i].onclick=function(){ 4 alert(1); 5 }; 6 } 7 console.timeEnd('test1');//火狐下测试 18ms 8 //下面是事件代理绑定事件 9 console.time('test2'); 10 oUl.onclick=function(e){ 11 e=e || event; 12 var t=e.target || e.srcElement; 13 if(t.nodeName.toLowerCase()=='li'){ 14 t.onclick=function(){ 15 alert(1); 16 }; 17 } 18 }; 19 console.timeEnd('test2');//火狐下测试 1.54ms
DOM与前端模板
- 更好的对逻辑和视图进行分离,MVC框架的基础