避免双重求值
有四个标准函数可以允许你传入代码的字符串,然后它才你动态执行。它们分别是:eval、Function、setTimeout、setInterval
事实上当你在javascript代码中执行另外一段javascript代码时,都会导致双重求值的性能消耗,所以在大多数情况下,没必要使得eval和Function函数,因此最好避免使用它们。至于setTimeout和setInterval,建议传入函数而不是字符串来作为第一个参数
现在Safari4和chrome的javaScript引擎会缓存住那些使用了eval且重复运行的代码,这也是一个性能提升点。
使用Object/Array直接量
使用直接量的两大好处
- 运行速度更快
- 节省代码量、减少文件尺寸(事实上对象属性或者数组项数量越多,使用直接量的好处就越明显)
不要重复工作
有两种方法避免重复工作
- 延迟加载
- 条件预加载
以一个例子来说明吧
function addHandler(target,eventType,handler) { if (target.addEventListener) {//DOM2 Events target.addEventListener(eventType, handler, false); } else {//IE target.attachEvent('on' + eventType, handler); } } function removeHandler(target, eventType, handler) { if (target.removeEventListener) {//DOM2 Events target.removeEventListener(eventType, handler, false); } else {//IE target.detachEvent('on' + eventType, handler); } }
事实上页面一加载,你就知道用户是使用的哪种浏览器,但是这时候如果页面上有100个元素需要添加事件绑定就需要判断100次(而本身事实上你只需要去判断一次)
下面使用延迟加载的方式来试试
function addHandler(target, eventType, handler) { if (target.addEventListener) {//DOM2 Events addHandler = function (target, eventType, handler) { target.addEventListener(eventType, handler, false); } } else {//IE addHandler = function (target, eventType, handler) { target.attachEvent('on' + eventType, handler); } } addHandler(target, eventType, handler);//调用新的函数 } function removeHandler(target, eventType, handler) { if (target.removeEventListener) {//DOM2 Events removeHandler = function (target, eventType, handler) { target.removeEventListener(eventType, handler, false); } } else {//IE removeHandler = function (target, eventType, handler) { target.detachEvent('on' + eventType, handler); } } removeHandler(target, eventType, handler);//调用新的函数 }
调用延迟加载函数时,第一次会相对慢些,后面每次调用时都会很快,所以当一个函数在页面中不会立即调用时,延迟加载是最好的选择
另外一种方式是使用条件预加载:会在脚本加载期间提单检测,而不会等到函数被调用
var addHandler = document.body.addEventListener ? function (target, eventType, handler) { target.addEventListener(eventType, handler, false); } : function (target, eventType, handler) { target.attachEvent('on' + eventType, handler); }; var removeHandler = document.body.removeEventListener ? function (target, eventType, handler) { target.removeEventListener(eventType, handler, false); } : function (target, eventType, handler) { target.detachEvent('on' + eventType, handler); };
位操作
javascript中的数字都是以64位格式进行存储的,在位操作中,数字被转换为有符号32位格式,每次运算都是直接操作该32位数得到结果,事实上javascript位操作比其它数学运算和布尔运算操作都要快
举例来说明一下
1、对2取模,一般性的大家会如下这样写
if (i % 2) { //是奇数 } else { //是偶数 }
但下面这样写会更快些
if (i & 1) { //是偶数 } else { //是奇数 }
2、位掩码(也就是使用单个数字的每一位来判定是否选项成立,从而有效的把数字转换为由布尔值标记组成的数组)示例代码如下所示
var OPTION_A = 1; var OPTION_B=2; var OPTION_C = 3; var OPTION_D = 4; var options = OPTION_A | OPTION_B | OPTION_C | OPTION_D; if (options&OPTION_A) { //选项a在列表中,进行处理processing } if (options & OPTION_B) { //选项b在列表中,进行处理processing }
使用原生方法
无论你的javascript如何优化,都不会比js引擎提供的原生方法更快,原因很简单这些原生方法在你写代码之前就已经存在浏览器中了,并且是使用低级语言写的,这就说明这些代码已经被编译成机器码成为浏览器的一部分了,启能不比你的代码快?