1、JS
a、缓存数组长度
循环无疑是和 JavaScript 性能非常相关的一部分。通过存储数组的长度,可以有效避免每次循环重新计算。
注: 虽然现代浏览器引擎会自动优化这个过程,但是不要忘记还有旧的浏览器。
var arr = new Array(1000), len, i; // Recommended - size is calculated only 1 time and then stored for (i = 0, len = arr.length; i < len; i++) { } // Not recommended - size needs to be recalculated 1000 times for (i = 0; i < arr.length; i++) { } |
b、避免全局查找
在一个函数中会用到全局对象存储为局部变量来减少全局查找,因为访问局部变量的速度要比访问全局变量的速度更快些
function search() { //当我要使用当前页面地址和主机域名 alert(window.location.href + window.location.host); } //最好的方式是如下这样 先用一个简单变量保存起来 function search() { var location = window.location; alert(location.href + location.host); } |
c、定时器
如果针对的是不断运行的代码,不应该使用setTimeout,而应该是用setInterval,因为setTimeout每一次都会初始化一个定时器,而setInterval只会在开始的时候初始化一个定时器
var timeoutTimes = 0; function timeout() { timeoutTimes++; if (timeoutTimes < 10) { setTimeout(timeout, 10); } } timeout(); //可以替换为: var intervalTimes = 0; function interval() { intervalTimes++; if (intervalTimes >= 10) { clearInterval(interv); } } var interv = setInterval(interval, 10); |
备注:两者之间的区别
setTimeout只在指定时间后执行一次,代码如下:[html] view plain copy
setInterval以指定时间为周期循环执行,代码如下:[html] view plain copy
两种方法根据不同的场景和业务需求择而取之, 一般情况下setTimeout用于延迟执行某方法或功能, setInterval则一般用于刷新表单,对于一些表单的假实时指定时间刷新同步 |
d、数字转换成字符串
最好用"" + 1来将数字转换成字符串,虽然看起来比较丑一点,但事实上这个效率是最高的,性能上来说:
("" +) > String() > .toString() > new String()
e、使用一次innerHTML赋值代替构建dom元素
对于大的DOM更改,使用innerHTML要比使用标准的DOM方法创建同样的DOM结构快得多。
var frag = document.createDocumentFragment(); for (var i = 0; i < 1000; i++) { var el = document.createElement('p'); el.innerHTML = i; frag.appendChild(el); } document.body.appendChild(frag); //可以替换为: var html = []; for (var i = 0; i < 1000; i++) { html.push('<p>' + i + '</p>'); } document.body.innerHTML = html.join(''); |
f、删除dom节点
删除dom节点之前,一定要删除注册在该节点上的事件,不管是用observe方式还是用attachEvent方式注册的事件,否则将会产生无法回收的内存。另外,在removeChild和innerHTML=’’二者之间,尽量选择后者. 因为在sIEve(内存泄露监测工具)中监测的结果是用removeChild无法有效地释放dom节点
g、避免双重循环
如果要提高代码性能,尽可能避免出现需要按照JavaScript解释的字符串,也就是
尽量少使用eval函数
使用eval相当于在运行时再次调用解释引擎对内容进行运行,需要消耗大量时间,而且使用Eval带来的安全性问题也是不容忽视的。
不要使用Function构造器
不要给setTimeout或者setInterval传递字符串参数
var num = 0; setTimeout('num++', 10); //可以替换为: var num = 0; function addNum() { num++; } setTimeout(addNum, 10); |
h、避免与null的比较
由于JavaScript是弱类型的,所以它不会做任何的自动类型检查,所以如果看到与null进行比较的代码,尝试使用以下技术替换
如果值应为一个引用类型,使用instanceof操作符检查其构造函数
如果值应为一个基本类型,作用typeof检查其类型
如果是希望对象包含某个特定的方法名,则使用typeof操作符确保指定名字的方法存在于对象上
i、松散耦合
1、解耦HTML/JavaScript
JavaScript和HTML的紧密耦合:直接写在HTML中的JavaScript、使用包含内联代码的<script>元素、使用HTML属性来分配事件处理程序等
HTML和JavaScript的紧密耦合:JavaScript中包含HTML,然后使用innerHTML来插入一段html文本到页面
其实应该是保持层次的分离,这样可以很容易的确定错误的来源,所以我们应确保HTML呈现应该尽可能与JavaScript保持分离
2、解耦CSS/JavaScript
显示问题的唯一来源应该是CSS,行为问题的唯一来源应该是JavaScript,层次之间保持松散耦合才可以让你的应用程序更加易于维护,所以像以下的代码element.style.color=”red”尽量改为element.className=”edit”,而且不要在css中通过表达式嵌入JavaScript
3、解耦应用程序/事件处理程序
将应用逻辑和事件处理程序相分离:一个事件处理程序应该从事件对象中提取,并将这些信息传送给处理应用逻辑的某个方法中。这样做的好处首先可以让你更容易更改触发特定过程的事件,其次可以在不附加事件的情况下测试代码,使其更易创建单元测试