移动Web应用程序开发 高性能JavaScript篇 (四) 数据访问和DOM编程

介绍

本系列博客将主要介绍如今大红大紫的移动Web应用程序开发最重要的三个工具:HTML5,JavaScript, CSS3。博文也分为三个大部分:

1. 众望所归的HTML5将主要介绍HTML5的前世今生,主要功能和API以及相关Demo,Demo的代码都可以在文章附件中下载到;

2. 高性能JavaScript将主要介绍如何让JavaScript更流畅,JavaScript debug和分析工具,可以说,没有JavaScript就不可能有互联网的今天,更不可能有移动互联网的明天,编写高性能的JavaScript至关重要;

3. 变化万千的CSS3将主要介绍如今异常强大的CSS3,结合HTML5编写动态的Web应用。熟练使用异常Fashion & Cool & 炫的CSS3将使Web应用增色不少。

本篇是高性能JavaScript介绍的第四篇,将给大家结合实例例子介绍JavaScript数据访问和DOM编程时,如何让Web应用或者网页更加高效。

相关文章

移动Web应用程序开发 高性能JavaScript篇 (一) JavaScript 性能瓶颈

移动Web应用程序开发 高性能JavaScript篇 (二) JavaScript 性能分析工具

移动Web应用程序开发 高性能JavaScript篇 (三) JavaScript 加载解析和部署

1. 数据访问

JavaScript中四种基本的数据存取位置:

1,直接量:只代表自己,不存储在特定位置,包括字符串、数字、布尔值、对象、数组、函数、正则表达式、null值、undefined值

2, 变量:var定义的数据存储单元

3,数组元素:存储在数组内部,以数字作为索引

4,对象成员:存储在对象内部,以字符串作为索引

直接量和局部变量的访问速度快于数组项和对象成员的访问速度。

一个函数被创建的作用域中对象的集合叫作函数的作用域链(键值对)

其中包括一个单独的可变对象(window, navigator, document等等)。

执行函数时,由运行期上下文(函数执行的环境)按对象在函数中出现的顺序生成活动对象(包括所有局部变量、命名参数、参数集合、this),然后将活动对象推入作用域链的前端。

函数访问数据时都需要去搜索运行期上下文的作用域链,查找同名的标识符,搜索过程从作域链头部开始,也就是当前运行函数的活动对象,直到找到为止。如果到最后还没找到,则认为该标识符是未定义的。并且,假如有多个同名的标识符的话,只会查找第一个。函数中读写局部变量是最快的,而读写全局变量是最慢的。

避免使用With(document等):把document等括号内的对象置 于作用域的头部,会使其它局部变量标识符的识别。

catch:把异常对象置于作用域的头部,同样会影响局部变量标识符的识别。

每一个JS 函数都表示为一个对象,该对象有一个内部属性[[Scope]],它包含了一个函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链(Scope chain),它决定哪些数据能被函数访问。函数作用域中的每个对象被称为一个可变对象(variable object)。当一个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象所填充。

例如下面这个全局函数:

function add(num1, num2) {

    var sum = num1 + num2;

    return sum;

}



由于此函数是在全局作用域下创建的,所以函数add() 的作用域链中只填入了一个单独的可变对象--全局对象:

前面add() 函数运行时对应的运行期上下文和作用域链:

函数执行时,每遇到一个变量都会进行一次标识符解析的过程,该过程从头至尾搜索作用域链,从当前运行函数的活动对象到全局对象,直至查找到同名的标识符,如果没找到则被认为是undefined。

关于数据访问更多内容可以参考:High performance JavaScript O'Reilly Yahoo Press 第二章 和 http://www.haogongju.net/art/1081558

2. DOM编程

由于DOM操作是一个耗费资源的操作,JavaScript脚本需要去Access页面资源,比直接脚本运行要慢很多,所以:

1. 在DOM编程中应该尽可能的减小DOM操作,并尽量使用JavaScript来代替DOM操作。

2. 对于经常使用的DOM操作,使用本地变量来存储一份引用以便经常使用。

下面我们用一个例子在对比一下下述两个例子:

代码一:

function innerHTMLLoop1() {

	for (var count = 0; count < 15000; count++) {

		document.getElementById('here').innerHTML += 'a';

	}

}

在Chrome中,运行时间为:

代码二:

function innerHTMLLoop2() {

	var content = '';

	for (var count = 0; count < 15000; count++) {

		content += 'a';

	}

	document.getElementById('here').innerHTML += content;

}

在Chrome中,运行时间为

明显可以看出代码二运行时间要少很多,效率明显优于代码一。

在DOM编程里还需要注意以下两点:

1. 在使用HTML collections 时候要非常小心,因为它代表了实时的全部的HTML document。典型的用法如下图所示:

2. 当页面包含多个事件操作的时候,可以使用event delegation来降低event handle 的数量,这样可以加快页面加载和操作的速度。关于这个话题的更多信息参考:http://www.sitepoint.com/javascript-event-delegation-is-easier-than-you-think/

示例代码下载地址: 下载

Para obtener información más completa sobre las optimizaciones del compilador, consulte nuestro Aviso de optimización.