为了提供新鲜, 别致的用户体验, 很多网站都会使用 JavaScript 来改善设计, 验证表单, 检查浏览器, 以及 Ajax 请求, cookie 操作等等, 实现无刷新动态效果 . 但是, 要将大量内容在浏览器呈现, 如果处理不好, 网站性能将会急剧下降. 所以我们有必要了解下, 如何提高 JavaScript 的执行效率.
一些提升 JavaScript 效率的方法:
一, 循环
1,for(;;) ~= while()>for(in),
这三种循环中 for(in)的效率极差, 因为他需要查询散列键, 只要可以就应该尽量少用. for(;;)和 while 循环的性能应该说基本 (平时使用时) 等价.
其次: 如果是循环变量递增或递减, 不要单独对循环变量赋值, 应该在它最后一次读取的时候使用嵌套的 ++ 或 -- 操作符. 如果要与数组的长度作比较, 应该事先把数组的 length 属性放入一个局部变量中, 减少查询次数.
2, 避免遍历大量元素, push()效率高于循环添加效率.
二, 局部变量和全局变量
1, 全局变量需要搜索更长的作用域链.
2, 全局变量的生命周期比局部变量长, 不利于内存释放.
3, 过多的全局变量容易造成混淆, 增大产生 bug 的可能性.
三, Eval (尽量避免使用)
使用 eval 相当于在运行时再次调用解释引擎对内容进行运行, 需要消耗大量时间. 这时候使用 JavaScript 所支持的闭包可以实现函数模版.
四, 减少对象查找
因为 JavaScript 的解释性, 所以 a.b.c.d.e, 需要进行至少 4 次查询操作, 先检查 a 再检查 a 中 的 b, 再检查 b 中的 c, 如此往下. 所以如果这样的表达式重复出现, 只要可能, 应该尽量少出现这样的表达式, 可以利用局部变量, 把它放入一个临时的地方进行查询.
这一点可以和循环结合起来, 因为我们常常要根据字符串, 数组的长度进行循环, 而通常这个长度是不变的, 比如: 每次查询 a.length, 就要额外进行一个操作, 而预先把 var len=a.length, 则就少了一次查询.
五, 字符串连接
如果是追加字符串, 最好使用 s+=anotherStr 操作, 而不是要使用 s=s+anotherStr. 如果要连接多个字符串, 应该少使用 +=, 如 s+=a;s+=b;s+=c; 应该写成 s+=a + b + c.
而如果是收集字符串, 比如多次对同一个字符串进行 += 操作的话, 最好使用一个缓存. 怎么用呢? 使用 JavaScript 数组来收集, 最后使用 join 方法连接起来,
如下:
- var buf = new Array();
- for(var i = 0; i <100; i++){
- buf.push(i.toString());
- }
- var all = buf.join("""");
六, 避开闭包陷阱
闭包是个强大的工具, 但同时也是性能问题的主要诱因之一. 不合理的使用闭包会导致内存泄漏. 闭包的性能不如使用内部方法, 更不如重用外部方法.
由于 IE 浏览器的 DOM 是用 COM 来实现的, COM 的内存管理是通过引用计数的方式, 引用计数有个难题就是循环引用, 一旦 DOM 引用了闭包(例如 eventhandler).
七, 文件优化与启用 Gzip 压缩
删除所有的空格和注释, 把代码放入一行内, 可以加快下载的速度, 注意, 是下载的速度而不是解析的速度, 如果是本地, 注释和空格并不会影响解释和执行速度.
Gzip 通常可以减少 70% 网页内容的大小, 包括脚本, 样式表, 图片等文件. Gzip 比 deflate 更高效, 主流服务器都有相应的压缩支持模块. Gzip 的工作流程为客户端 在请求 Accept-Encoding 中声明可以支持 gzip 服务器将请求文档压缩, 并在 Content-Encoding 中声明该回复为 gzip 格式客户端收到之后按照 gzip 解压缩.
八, JS 延迟加载
一些不需要立即使用的代码可以延迟时间加载, 不需要立即加载进去. 可在需要用到时候通过某一机制来触发,
加载. 如:
- <script>
- var oHead = document.getElementsByTagName('HEAD').item(0);
- var oScript= document.createElement("script");
- oScript.type = "text/javascript";
- oScript.src="testload.js";
- oHead.appendChild( oScript);
- </script>
- // 可以把上诉代码封装为一个函数, 传递两个参数进去, 通过某一机制触发这个函数, 达到动态加载 JS 的效果.
- <script>
- function(style,src)
- var oHead = document.getElementsByTagName('HEAD').item(0);
- if(style=='javascript'){
- var oScript= document.createElement("script");
- oScript.type = "text/javascript";
- oScript.src=src;
- oHead.appendChild( oScript);
- }else{
- var oLink= document.createElement("link");
- oLink.type = "text/CSS";
- oLink.rel = "stylesheet";
- oLink.href=src;
- oHead.appendChild( oLink);
- }</script>