1.对象属性查找越少越好
使用变量和数组访问比访问对象上的属性效率更高,因为访问属性是一个O(N)的操作(访问属性需要遍历)
例子:
/*写法一,直接寻找*/ var query1=window.location.href.substring(window.location.href.indexOf('?')); /*第二种写法,添加局部变量*/ var url=window.location.href; var query2=url.substring(url.indexOf('?'));
这样写的第二种方法将会比第一种节省近33%的成本,因为节省了属性访问的成本(相比较访问数组和变量,这是个更大的消耗)
2.避免双重解释(尽量不要用字符串的方式写js代码)
直接上示例:
// 给某些代码求值——避免 eval("alert('Hello World')"); // 创建新的函数——避免 var sayHI=new Function("alert('Hello World')"); // 设置超时——避免 setTimeout("alert('Hello World')",500); //直接修正 alert('Hello World'); // 创建新函数——修正 var sayHI=function(){ alert('Hello World'); } // 设置一个超时 setTimeout(function(){ alert('Hello World'); },500);
避免的原因:字符串javascript代码不能在初始的解析过程中完成,javascript代码运行的同时必须新启动一个解析器来解析新的代码,实例化一个新的解析器有不容忽视的开销,这种代码解析要比直接解析慢很多
3.高频事件的防抖处理
在处理一些高频变化事件,比如鼠标位置检测,拖动效果,浏览器窗口变化的时候,会产生高频触发,如果回调函数过重,就有可能使得浏览器卡死,解决办法就是——防抖,防抖可以限制一个方法在一定时间内执行的次数
1 // 取自 UnderscoreJS 实用框架 2 function debounce(func, wait, immediate) { 3 var timeout; 4 return function() { 5 var context = this, args = arguments; 6 var later = function() { 7 timeout = null; 8 if (!immediate) func.apply(context, args); 9 }; 10 var callNow = immediate && !timeout; 11 clearTimeout(timeout); 12 timeout = setTimeout(later, wait); 13 if (callNow) func.apply(context, args); 14 }; 15 } 16 17 // 添加resize的回调函数,但是只允许它每300毫秒执行一次 18 window.addEventListener('resize', debounce(function(event) { 19 20 // 这里写resize过程 21 22 }, 300));
这样就可以比较好的兼容页面效果实现和浏览器处理计算。
4.网络存储的静态缓存和非必要内容优化
一种策略是去使用Session存储来存 储非必要的,更为静态的内容,例如侧边栏的HTML内容,从Ajax加载进来的文章内容,或者一些其他的各种各样的片断,是我们只想请求一次的。
而在html5的时代,我们可以实现5M的本地存储,localStorage为我们提供了很大的可能性,页面一般会超过5M,可以存储很多东西了。
5.使用异步加载,延迟加载依赖
XMLHttpRequest(该对象可以调用AJAX)使得资源的异步加载变得流行起来,它允许无阻塞资源加载,并且使 onload 启动更快,允许页面内容加载,而不需要刷新页面。 比较常见的方式是按需加载,一开始只加载能看到的部分,看不到的部分需要到滚动条触发的时候才加载,这也可以 大大提升用户体验(或者整个页面默默地不停的在后台加载,实现快速浏览之类)。
6.使用css动画代替js动画
现在的css3支持很多内置的动画,也有很多传统的动画效果是通过javascript实现的,实际上,css3实现动画的效率将会比js实现效率更高,因为很多计算都是在cpu处理的,所以会很流畅。而且css相对而言会减少很多代码量,使用更加方便。另外,javascript实现动画的时候,使用requestAnimationFrame代替setTimeout和setInterval也会提高动画流畅度,requestAnimationFrame方法类似于css3的实现方式,也是cpu处理动画执行方式,可以保证动画帧数为60帧左右。详细用法请移步:《尝试新东西——requestAnimationFrame》
7.使用事件委托
事件委托机制常用于在父级元素上添加一个事件监听器,用来代替给每一个子元素添加事件监听,当事件触发的时候,event.target就是评估相应的措施是否需要被执行。比较大的优势体现在如果子元素需要重复的加载或者是删除的的时候,不需要重新去遍历节点
8.在繁重重复的执行任务上使用web workers(多线程)
有些任务不需要访问dom,但是却要进行大量麻烦的计算,这种模式我们就可以用web workers模式来完成,另开一个线程不会影响到现在的页面js执行,这是很方便的事情。不过web workers还是有一定的局限性:
1.不能跨域加载JS
2.worker内代码不能访问DOM
3.各个浏览器对Worker的实现不大一致,例如FF里允许worker中创建新的worker,而Chrome中就不行
4.不是每个浏览器都支持这个新特性
优势:
1.可以加载一个JS进行大量的复杂计算而不挂起主进程,并通过postMessage,onmessage进行通信
2.可以在worker中通过importScripts(url)加载另外的脚本文件
3.可以使用 setTimeout(), clearTimeout(), setInterval(), and clearInterval()
4.可以使用XMLHttpRequest来发送请求
5.可以访问navigator的部分属性