
1.5 优化jQuery和DOM交互
jQuery是一个被广泛使用的JavaScript库,它能用简洁方便灵活的方式来访问和操作DOM元素,还可以减轻跨浏览器问题,使得你可以集中于核心应用开发而不是浏览器兼容问题。jQuery以选择器引擎为核心,是你能以熟悉的CSS样式的选择器语言来找到DOM元素。例如,下面的代码返回一个jQuery对象(一种数组)包含所有具有“big” CSS类的图像元素:

或jQuery简写方式:

$images变量只是一个普通变量,前面的$仅仅是提醒它引用一个jQuery对象。
有一点需要特别注意的是:一个看似简单无害的jQuery语句会在幕后做很多工作。如果只偶尔访问少量的元素,还没有太大关系。不过,如果要连续访问许多元素,比如在一个动画感很强的页面,就会严重地影响性能。
1.5.1 优化CSS格式变化
用DHTML创建JavaScript图形的一个基本操作就是快速操作DOM元素的CSS样式属性。在jQuery中,你可以这么做:

这个语句会找到id是element1的元素,并修改其CSS颜色样式为红色。
这个语句分解开来做了这么些事:
- 调用jQuery并让它在DOM中搜索一个id为element1的元素。除了搜索本身之外,它还涉及进行正则表达式测试来决定需要搜索的类型。
- 返回找到的元素列表,一个特殊的jQuery数组对象。
- 调用jQuery的css()函数。这会进行不同的检查,如决定是读或写,是否传入一个字符串参数、对象或者更多,最后更新元素样式本身。
连续进行这类的工作将会很慢,不管jQuery如何高效:

因为这里每行进行一次id为element1元素的搜索,这样很没有效率。
一个更快的方法是指定jQuery应该搜索的范围。jQuery默认情况下要从document根或DOM层次的最上层开始搜索。而在许多情况下,这是没有必要的。如果你指定一个范围,会减少jQeury的搜索工作,更快地返回结果。
下面的例子搜索所有具有alien CSS类的元素,从环境参数(container)内的DOM元素中开始搜索:

环境参数的类型是灵活的,可以是另一个jQuery对象或CSS选择器:

当然要确保搜索环境不比搜索元素本身慢。如果可能的话,应尽量直接引用DOM元素。
理想情况下,一旦元素被找到,你不应该再重新搜索它们。我们可以将搜索结果存起来:

不过上面的代码中jQuery的css()函数调用还是做了额外的工作,我们可以直接引用到DOM元素的实际式样对象中:

图1-7显示了前面3种方式的性能结果。在页面更复杂、CSS选择器更慢的情况,这种差别会更加明显。

图1-7 3种方式的速度比较(原始方式、保存元素对象的方式、直接写元素CSS式样的方式)
直接操作元素的属性本身比使用jQuery更快。比如,jQuery.html()方法要比直接使用一个元素的innerHTML对象要慢许多。
图1-7的结果意味着我们应该完全不使用jQuery吗?不是,jQuery是不容错过的,在某些环境下慢些是可以理解和接受的。但在速度很关键的代码区内应注意jQuery的使用方式。这通常只是所有代码中的一小部分。你的大部分应用程序可以(也应该)使用jQuery来快速方便地进行开发。
1.5.2 优化DOM插入
如果你的应用需要加入大量的元素到DOM中,可能会影响性能。DOM是一个复杂的数据结构,应尽量少去修改。这在动态Web页面中当然是不太可能的,因此你需要一个高效的方式来插入元素。
你可以通过jQuery来插入一个元素到DOM中:

这对几个元素来说是足够了,但当你需要插入成百上千个元素时,单个插入这些元素会太慢。
更好的方式是将所有要插入的元素构建为一个大的字符串,然后一次插入。对每个元素,这防止了jQuery调用和进行各种内部测试的开销。
