优化 JavaScript 代码
2009-06-26 16:38:33 来源:Yeeyan译言 【大 中 小】 评论:0 条 我要投稿
主机网全新上线,买空间、服务器就上主机网,安全有保障!CNIDC.COM
作者: Gregory Baker, GMail 软件工程师 和 Erik Arvidsson, Google Chrome 软件工程师
需要的经验: JavaScript 相关工作知识
客户端脚本能让你的应用更加地动态和活跃, 但是浏览器对代码的解析可能造成效率问题, 而这种性能差异在客户端之间也不尽相同。 这里我们讨论和给出一些优化你的 JavaScript 代码的提示和最佳实践。
使用字符串
字符串连接操作会对 Internet Explorer 6 和 7 的垃圾收集带来很大的影响。 尽管这个问题在 Internet Explorer 8 里面得到解决 -- 字符串连接在 IE8 和其它非 IE 浏览器(如 Chrome)中稍微更有效率一点 -- 如果你的用户中有很大一部分在使用 Internet Explorer 6 或 7, 你就需要非常注意你构建字符串的方式了。
有如下示例代码:
以下为引用的内容:
var veryLongMessage =
'This is a long string that due to our strict line length limit of' +
maxCharsPerLine +
' characters per line must be wrapped. ' +
percentWhoDislike +
'% of engineers dislike this rule. The line length limit is for ' +
' style purposes, but we don't want it to have a performance impact.' +
' So the question is how should we do the wrapping?';
比起用连接的方式, 尝试使用 join():
以下为引用的内容:
var veryLongMessage =
['This is a long string that due to our strict line length limit of',
maxCharsPerLine,
' characters per line must be wrapped. ',
percentWhoDislike,
'% of engineers dislike this rule. The line length limit is for ',
' style purposes, but we don't want it to have a performance impact.',
' So the question is how should we do the wrapping?'
].join();
相似的, 用连接的方式在条件语句和循环中构建字符串是很低效的。 错误的方式:
以下为引用的内容:
var fibonacciStr = '前 20 个斐波那契数 ';
for (var i = 0; i < 20; i++) {
fibonacciStr += i + ' = ' + fibonacci(i) + '
';
}
正确的方法:
以下为引用的内容:
var strBuilder = ['前 20 个斐波那契数:'];
for (var i = 0; i < 20; i++) {
strBuilder.push(i, ' = ', fibonacci(i));
}
var fibonacciStr = strBuilder.join('');
构建通过辅助函数生成的字符串
通过传递字符串构建器(可以是数组或者辅助类)到函数中构建长字符串, 以避免出现存放临时结果的字符串。
例如, 假定 buildMenuItemHtml_ 需要用文字串和变量构建一个字符串, 并且会在内部使用一个字符串构建器, 与其使用:
以下为引用的内容:
var strBuilder = [];
for (var i = 0; i < menuItems.length; i++) {
strBuilder.push(this.buildMenuItemHtml_(menuItems[i]));
}
var menuHtml = strBuilder.join();
不如用:
var strBuilder = [];
for (var i = 0; i < menuItems.length; i++) {
this.buildMenuItem_(menuItems[i], strBuilder);
}
var menuHtml = strBuilder.join();
定义类的方法
下面的代码效率不高, 因为每次构造 baz.Bar 的实例时, 都会为 foo 创建一个新函数和闭包(closure):
以下为引用的内容:
baz.Bar = function() {
// 构造函数代码
this.foo = function() {
// 方法代码
};
}
推荐的方式为:
baz.Bar = function() {
// 构造函数代码
};
baz.Bar.prototype.foo = function() {
// 方法代码
};
用这种方式, 无论构造了多少个 baz.Bar 实例, 只会创建一个函数给 foo, 同时不会创建任何闭包。
初始化实例变量
将带有值类型(非引用的)的初始化值(例如类型为数字, 布尔值, null, undefined 或字符串的值)的变量声明/初始化代码直接放在 prototype 原型中。 这可以避免每次调用构造函数时不必要地运行初始化代码。(这个方法无法应用到初始化值由构造器参数决定或构造时状态不确定的实例变量上。)
例如, 比起写:
以下为引用的内容:
foo.Bar = function() {
this.prop1_ = 4;
this.prop2_ = true;
this.prop3_ = [];
this.prop4_ = 'blah';
};
不如写:
foo.Bar = function() {
this.prop3_ = [];
};
foo.Bar.prototype.prop1_ = 4;
foo.Bar.prototype.prop2_ = true;
foo.Bar.prototype.prop4_ = 'blah';
谨慎地使用闭包(closure)
闭包是 JavaScript 中一个强大而有用的特性; 但是, 它们也有不好的地方, 包括:
它们是最常见的内存泄漏源头。
创建一个闭包比创建一个没有闭包的内联函数明显要慢, 比起重用一个静态函数则更慢。 例如:
以下为引用的内容:
function setupAlertTimeout() {
var msg = '要显示的消息';
window.setTimeout(function() { alert(msg); }, 100);
}
比下面的代码慢:
function setupAlertTimeout() {
window.setTimeout(function() {
var msg = '要显示的消息';
alert(msg);
}, 100);
}
更比下面的代码慢:
function alertMsg() {
var msg = '要显示的消息';
alert(msg);
}
function setupAlertTimeout() {
window.setTimeout(alertMsg, 100);
}
他们增加了作用域链(scope chain)的层级。 当浏览器解析属性时, 作用域链的每一个层级都必须被检查一次。 在下面的例子中:
以下为引用的内容:
var a = 'a';
function createFunctionWithClosure() {
var b = 'b';
return function () {
var c = 'c';
a;
b;
c;
};
}
var f = createFunctionWithClosure();
f();
当 f 被调用时, 引用 a 比引用 b 慢, 它们都比引用 c 要慢。
查看 IE+JScript Performance Recommendations Part 3: JavaScript Code inefficiencies 获得更多有关在 IE 中使用闭包的信息。
避免使用 with
在你的代码中避免使用 with. 它对性能有非常坏的影响, 因为它修改了作用域链, 让查找在其它作用域的变量变得代价高昂。
避免浏览器内存泄漏
内存泄漏对 Web 应用而言是个很普遍的问题, 它会带来严重的性能问题。 当浏览器的内存使用上升时, 你的 Web 应用,连同用户系统的其他部分, 都会变慢。 Web 应用最常见的内存泄漏原因是: 在 JavaScript 脚本引擎和浏览器 DOM 的 C++ 对象实现间的循环引用(例如, 在 JavaScript 脚本引擎和 Internet Explorer 的 COM 基础架构间, 或者 JavaScript 引擎和 Firefox 的 XPCOM 基础架构间)。
下面是避免内存泄漏的一些经验法则:
使用一个事件系统来附加事件处理函数
最常见的循环引用模式 [ DOM 元素 --》 事件处理函数 --》 闭包作用域 --》 DOM ] 在 这篇 MSDN 的 Blog 文章中讨论过了。 为避免这个问题, 可以使用一个经过严格测试的事件系统来附件事件处理函数, 例如 Google doctype, Dojo, or JQuery.
另外, 在 IE 中使用内联(inline)的事件处理函数会导致另外一类泄漏。 这不是通常的循环引用泄漏, 而是内存中临时匿名脚本对象的泄漏。 详情请查看 理解和解决 IE 泄漏模式(Understanding and Solving Internet Explorer Leak Patterns) 的 “DOM 插入顺序泄漏模型(DOM Insertion Order Leak Model)” 一节, 另外在 JavaScript Kit 教程 中还有一个例子。
避免使用扩展(expando)属性
扩展属性是附加到 DOM 元素上的任意 JavaScript 属性, 也是循环引用的常见原因。 你能够在使用扩展属性时不导致内存泄漏,但是很容易不小心就引入一个泄漏。 这个泄漏的模式是 [ DOM 元素 --》 扩展属性 --》 中间对象 --》 DOM 元素 ]。最好的方法就是避免使用它们。 如果你要使用它们, 就只使用简单的值类型。 如果你要非简单的类型,那么在不再需要扩展属性时将它设为空(null)。 参见 理解和解决 IE 泄漏模式(Understanding and Solving Internet Explorer Leak Patterns) 中的 “循环引用(Circular References)” 一节.
分享到:
相关推荐
优化 JavaScript 代码 作者: Gregory Baker, GMail 软件工程师 和 Erik Arvidsson, Google Chrome 软件工程师 需要的经验: JavaScript 相关工作知识 客户端脚本能让你的应用更加地动态和活跃, 但是浏览器对代码的...
用 JS 编写的粒子群优化库。适用于RequireJS,来自WebWorker,在node.js或普通浏览器环境中。 示例应用程序 simple优化一维函数的简单应用程序 simple-require和simple一样,除了使用 RequireJS simple-node一个...
JavaScript代码优化一例.pdf
目录: 第1课 第一页 Javascript高级教程 第二页 本教程的课程计划 第三页 一个if-then-else的快捷方式 第四页 什么是变量 第五页 变量的使用方法 ...第六页 按速度优化JavaScript代码 第七页 下面讲什么?
主要介绍了JavaScript异步代码优化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
用斐波那契记忆优化法优化递归,提高代码运行效率,这个是JavaScript版
应用jQuery技术优化传统JavaScript代码制作网页块元素悬停功能.pdf
下面我们通过这个例子介绍1个更简单的方法: 我们用将统计代码保存到1个文件:文件路径:/config/counter.conf 统计代码如下: 代码如下: [removed] var _gaq = _gaq || []; _gaq.push([‘_setAccount’, ‘UA-18744406-...
此外,很多程序辛辛苦苦的写出来的javascript代码却被别人随意的剽窃,实为憾事。本软件还可以通过对javascript的变量名称和过程名称进行编码,从而起到混淆ja代码的作用,保护您的劳动成功。 JS代码压缩,基本原理...
javascript 中粒子 群优化 的可视化_javascript _代码_下载
JavaScript代码格式化,对凌乱的JavaScript代码进行格式化,保持代码的整洁,挺好用的一个工具,虽然对于一些正则表达式的格式化效果有点不太好,但整体还是比较清晰的,毕竟我们的程序也只有那某个脚本文件是正则吧...
本篇文章给大家分享了关于javascript代码优化的8点总结,希望我们整理的内容能够帮助到大家。
NULL 博文链接:https://t240178168.iteye.com/blog/1702269
优化CSS,Javascript代码(Minify+Uglify)以减少带宽占用,提高网页打开速度 教程
JavaScript Analyser是一款高效的JavaScript分析、压缩工具,旨在提供一款安全、可靠的压缩工具,帮助开发者优化JavaScript代码、提高网站性能。该工具支持语法压缩、文本压缩两步骤,可以根据文件大小和压缩率选择...
cxVzxvcxvxzcvcxzvcasdA wefcccccccccccccccccccccccccewcccccccccccccccc
Javascript 代码压缩 网址 : http://julying.com/lab/compress-js-css/ 类型: 原创脚本 作者: 王子墨 邮箱 : i@julying.com 发布 : 2012-06-10 22:28 更新 : 2012-07-22 12:50 版权所有 2012 | julying....