最近在研究js的性能问题,总结了几点最基本的js优化。
1:JS的脚本位置
浏览器在解析到body之前,不会渲染页面的任何部分,推荐将<script>标签放在body的底部,减少对整个页面下载的影响。因此优化js的首要规则将脚本放在底部。
2:合并js脚本,减少外联脚本的数量
浏览器在解析到<script>标签的时候,都会因为执行脚本导致一定的时延。因此合并js文件减少页面外联脚本的数量将改善性能。
3:把多次访问的全局变量(对象成员,数组元素,跨域变量)储存为局部变量。
在执行环境的作用链中,局部变量在作用链的顶端而全局变量在执行环境的作用链的末端,因此将全局变量存储为局部变量减少了全局变量的查找时间。
4:访问Dom的次数越多,代码的运行速度越慢。减少DOM的访问次数能有效提高性能。
1 function innerHtml(){ 2 for(var count=0;count<1500;count++){ 3 document.getElementById('here').innerHTML+='a' 4 } 5 }
改进后:
function innerHtml(){ var content=''; for(var count=0;count〈15000;count++){ content+='a'; } document.getElementById('here').innerHTML+=content; }
5:现在大多数浏览器提供的apI只能返回元素节点,在所有浏览器中children都要比childNode要快,但IE中遍历children要比childNode要快。
6:在元素查找的时候可以都是用html5新的api比如。querySelectorAll(), querySelector()
var elements=document.querySelectorAll("#menu a")
这个返回的不是一个html集合而是一个NodeList(包含匹配节点的类数组对象)不用遍历可以直接使用。
7:最小化重绘和重排
先解释2个概念: 重排:在一些情况下浏览器会使渲染树的部分失效并重新绘制渲染树叫重绘
重绘: 在重绘后浏览器会重新绘制受影响的部分到屏幕上叫做重绘。
重绘和重排操作会使web应用程序的IU反应迟钝,应该减少这类过程的发生。每次重排都会产生计算机的消耗,大多数的浏览器通过对列化修改并批量执行来优化,但是在我们获取布局信息操作时(需要返回最新的布局信息,浏览器不得不执行渲染队列中的待处理变化)会导致队列的刷新,并使计划任务强制执行。比如访问以下方法,offsetTop,offsetLeft.....
一个有效的方法合并对Dom和样式的修改然后一次性处理掉
var el=document.getElementById('myDiv'); el.style.cssText='border-left:1px;border-right:2px;"
批量修改Dom,先使元素脱离文档流,对齐进行操作,然后再将元素带回文档。
有3种方法可以使元素脱离文档
1:隐藏元素
var ul=document.getElementById("myUL"); ul.style.display="none"; 对ul的一系列操作 ul.style.display="block";
2:在文档之外创建并更新一个文档片段 (最好的方法)
var fragment=document.createDocumentFragment(); 一些列操作 document.getElmentById("myUL").appendChild(fragment)
3:对要修改的节点创建一个备份然后对备份进行修改
var old=document.getElementById('myUL'); var clone=old.cloneNode(true); 一系列操作 old.parentNode.replaceChild(clone,old);
8:使用事件委托机制减少创建事件的开销。在父元素中注册事件,利用冒泡机制检测执行父元素的所有子元素的事件。
document.getElemntById("mulisi').onclick=function(e){ e=e||window.event; var target=e.target||e.srcElement; if(target,nodeName=='A'){ } if(target.nodeName=="LI'){ } ... }
9:使用web worker缓解ui线程的压力
1 var worker=new worker('json.js'); 2 worker.onmessage=function(event){ 3 var jsonDate=event.data; 4 //使用解析了的json数据 5 use(jsonDate); 6 } 7 //传入要解析的json数据 8 worker.postMessage(jsonText);
json.js
self.onmessage=function(event){ var jsonText=event.data; //解析json var json=JSON.parse(jsonText); //回传结果 self.postMessge(json); }
web workers常用的地方
1:编码解码大字符串
2:复杂数学运算
3:大数组排序
10:使用定时器把长时间运行的任务分解成小任务,防止UI线程的锁定。