首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

提高 web 应用性能之 JavaScript 性能调优 (1)

提高 web 应用性能之 JavaScript 性能调优 (1)

简介Web 开发中经常会遇到性能的问题,尤其是针对当今的 Web2.0 应用。JavaScript 是当今使用最为广泛的 Web 开发语言,Web 应用的性能问题很大一部分都是由程序员写的 JavaScript 脚本性能不佳所造成的,里面包括了 JavaScript 语言本身的性能问题,以及其与 DOM 交互时的性能问题。本文主要来探讨一下如何尽可能多的避免这类问题,从而最大限度的提高 Web 应用的性能。
JavaScript 性能调优JavaScript 语言由于它的单线程和解释执行的两个特点,决定了它本身有很多地方有性能问题,所以可改进的地方有不少。
eval 的问题:比较下述代码:
清单 1. eval 的问题
1
2
3
4
5
var reference = {}, props = “p1”;
eval(“reference.” + props + “=5”)

var reference = {}, props = “p1”;
reference[props] = 5




有“eval”的代码比没有“eval”的代码要慢上 100 倍以上。
主要原因是:JavaScript 代码在执行前会进行类似“预编译”的操作:首先会创建一个当前执行环境下的活动对象,并将那些用 var 申明的变量设置为活动对象的属性,但是此时这些变量的赋值都是 undefined,并将那些以 function 定义的函数也添加为活动对象的属性,而且它们的值正是函数的定义。但是,如果你使用了“eval”,则“eval”中的代码(实际上为字符串)无法预先识别其上下文,无法被提前解析和优化,即无法进行预编译的操作。所以,其性能也会大幅度降低。
Function 的用法:比较下述代码:
清单 2. function 的用法
1
2
3
4
5
var func1 = new Function(“return arguments[0] + arguments[1]”);
func1(10, 20);

var func2 = function(){ return arguments[0] + arguments[1] };
func2(10, 20);




这里类似之前提到的“eval”方法,这里“func1”的效率会比“func2”的效率差很多,所以推荐使用第二种方式。
函数的作用域链(scope chain):JavaScript 代码解释执行,在进入函数内部时,它会预先分析当前的变量,并将这些变量归入不同的层级(level),一般情况下:
局部变量放入层级 1(浅),全局变量放入层级 2(深)。如果进入“with”或“try – catch”代码块,则会增加新的层级,即将“with”或“catch”里的变量放入最浅层(层 1),并将之前的层级依次加深。
参考如下代码:
清单 3. 函数作用域链
1
2
3
4
5
6
7
8
9
10
11
12
var myObj = … ..
… ..
function process(){
var images = document.getElementsByTagName("img"),
widget = document.getElementsByTagName("input"),
combination = [];
for(var i = 0; i < images.length; i++){
combination.push(combine(images, widget[2*i]));
}
myObj.container.property1 = combination[0];
myObj.container.property2 = combination[combination.length-1];
}




这里我们可以看到,“images”,“widget”,“combination”属于局部变量,在层 1。“document”,“myObj”属于全局变量,在层 2。
变量所在的层越浅,访问(读取或修改)速度越快,层越深,访问速度越慢。所以这里对“images”,“widget”,“combination”的访问速度比“document”,“myObj”要快一些。所以推荐尽量使用局部变量,可见如下代码:
清单 4. 使用局部变量
1
2
3
4
5
6
7
8
9
10
11
12
13
var myObj = … ..
… ..
function process(){
var doc = document;
var images = doc.getElementsByTagName("img"),
widget = doc.getElementsByTagName("input"),
combination = [];
for(var i = 0; i < images.length; i++){
combination.push(combine(images, widget[2*i]));
}
myObj.container.property1 = combination[0];
myObj.container.property2 = combination[combination.length-1];
}




我们用局部变量“doc”取代全局变量“document”,这样可以改进性能,尤其是对于大量使用全局变量的函数里面。
返回列表