1. 尽量使用id选择元素

当使用id选择元素时,jQuery调用浏览器的document.getElementById()进行选择元素,而使用class进行选择元素时,由于DOM本身不支持通过class进行选择元素,所以jQuery不得不遍历真个Dom文档来判断每个元素是否包含要选择的class,我使用firebug的console时间记录分析,在我电脑上id大概比class快10倍,如果页面内容很多,快的就越多,测试代码如下:

console.time('class');
for (var i = 0; i < 10000; i++)
$(".content");
console.timeEnd('class');
console.time('id');
for (var i = 0; i < 10000; i++)
$("#header");
console.timeEnd('id');

元素选择器的性能比class快一些,而比id要慢一些,因为当用元素进行选择时可以调用document.getElementsByTagName(),所以优先id,元素次之,class最差。

2.当必须用元素或class选择器时,尽量使用离它最近的祖先节点的id作为前缀

例如 $(“.content”)和$(“#left .content”),前者需要遍历整个DOM文档,而$(“#left .content”)则可以先调用document.getElementById(“#left”),这一步的开销可以忽略,然后在#left元素的后代里进行遍历,#left 和.content离得越近,需要遍历的元素就越少,所以使用祖先里id作为前缀可以获得一定的性能提升,取决整个文档结构。

3.当必须用元素或class选择器时,尽量把该元素的元素标签作为前缀

在第一条里说过,元素选择器要比class选择器快,所以$(“div.content”)要比$(“.content”)快一些,在我电脑上测试结果是大概快15%左右,当然也可以把第二条和第三条结合起来一起使用。

4. 查询时使用上下文(context)来减少查询次数

JQuery查询时有一个可选参数context, 即$(express, [context]), context可以是dom元素,元素集和JQuery对象。Context的作用是设定查询的范围,默认是document,所以$(“a”)等同于$(“a”, document), 我们可以通过给定context值来减少查询范围,例如我只想在<div id=”#header”>…</div>里进行查找a标签,就可以使用$(“a”, document.getElementById(“#header”)), 记住,第二个参数context一定要是一个DOM对象才能提高性能,如果是$(“a”,”#header”),虽然可以用,但不会提升性能,因为JQuery会自动把它转换成$(“#header”).find(“a”);

这一条和第二条以及第三条相似,都是通过限定查询范围来减少查询次数,尤其是dom结构比较复杂的页面,效果更是明显。

5.缓存查询结果,减少查询次数 通过元素或class进行查询时非常消耗性能的,因此应该尽量减少查询次数,例如:

for (var i = 0; i &lt; 1000; i++) {
    $(".content").append(i);
}

上面的代码需要对同一个元素进行1000次查询,浪费了大量时间,可以查询的结果保存下来以供后面使用来减少查询次数,var content = $(“.content”);

for (var i = 0; i &lt; 1000; i++) {
  content.append(i);
}

6. 通过链式操作减少查询次数以及代码量

通常jQuery的函数调用会返回上一次查询的元素,例如我们要设置元素的宽度和高度,通常我们会分别调用函数来完成,$(“.content”).width(100);

$(“.content”).height(100);width()和height()函数的返回值都是$(“.content”),因此$(“.content”).width(100).height(100)来减少一次查询,当然我们可以写得非常长,例如:

$(“.content”).width(100).height(100).show().fadeIn().addClass(‘abc’);

7.尽量减少直接进行DOM操作

直接操作DOM是比较慢的,因此如果频繁的操作DOM会带来很大的性能问题,典型的例子是向DOM里插入元素,例如,我们要向body结尾插入1000个p元素,

第一种方法:

for (var i = 0; i < 1000; i++)
$(“body”).append(‘<p>ddd</p>’);
第二种方法:
var sss = ”; for (var i = 0; i < 1000; i++) { sss += ‘<p>ddd</p>’; } $(“body”).append(sss);
第一种方法要进行1000次dom操作,而第二种方法只要进行一次dom操作,并且字符串拼接的速度比dom操作要快很多,所以第二种方法可以带来很大的性能提升。因此对于dom操作,尽量先用字符串拼接好,然后一次插入。

8.尽量减少事件代理

大量的事件代理会带来很大的性能问题,例如我们要给100个列表元素添加事件,就是100个事件代理,如果元素更多,性能会更差,我们可以利用事件的冒泡特性来减少代理,具体就是我们把事件代理放在这个100个列表元素的父节点
ul元素上,当事件发生时会传递(冒泡)到他们的父节点上,然后再判断是哪个元素发生了点击行为,代码如下:

$('ul#myList).bind('click', function(e){
	var target = e.target, // e.target grabs the node that triggered the event.
	$target = $(target);  // wraps the node in a jQuery object
	if (target.nodeName === 'LI') {
		$target.addClass('clicked');
		// do stuff
	}
});

JQuery1.4.2引入了.delegate()函数,可以更方便的处理事件代理,代码如下:
$(“ul#myList”).delegate(“li”, “click”, function() {$(this).addClass(‘clicked’);});
delegate()函数不仅可以方便的处理事件代理,还可以起到类似.live()函数的作用,即对于后面加入的元素也起作用。

9.使用data()来保存数据

平常大家有临时数据要保存时通常是保存在class中或自定义一个属性来保存,例如<div class=”123″></div>或者<div count=”3″></div>,其实这些方式使用起来不太方便,同时也给HTML添加了大量无意义的数据,同时基本上也只能存储字符串,JQuery内置了.data()函数来存储数据,可以任意类型的数据,包括对象,

$("#abc").data('count', 3);//存数据
var count = $("#abc").data('count')//读数据
$("#abc").removeData('count');//删除数据

这种方法使用方便,而且不会对HTML结构带来影响,非常简洁

10.尽量减少不必要代码执行数量

所谓不必要的代码主要是指在当前页面根本不需要执行的代码,这些代码可能是其它页面需要的,这种情况非常常见,尤其是只有一个js文件时,所有页面的代码在每个页面都会执行一遍。最理想的情况是每个页面只执行每个页面各自的代码,但这会带来严重的代码组织维护问题。例如:

$("#a").click(function() {...});//page a需要执行的代码
$("#b").click(function() {...});//page b需要执行的代码
$("#c").click(function() {...});//page c需要执行的代码

page a载入时会把上面的代码都执行一遍,很明显后面两行代码不应该执行的,虽然JQuery对于查询失败时处理得比较好,但是查询成功和查询失败花的时间是差不多,只是失败后就不会执行后续的操作,因此我们可以通过判断某个元素是否存在来决定是否执行该代码,

if ($("#a").length > 0) {....} //只有是page a才执行
if ($("#b").length > 0) {....} //只有是page b才执行
if ($("#c").length > 0) {....} //只有是page c才执行

以上这种方式对于有非常多代码的文件来说特别有效,可以减少大量不必要的查询,要知道通过class进行查询是特别消耗时间的,当然了,对于大的网站来说可以把不同页面的代码放到不同的文件里,然后知载入需要的js文件。

11.使用良好的命名方式来区分jQuery对象和普通的JavaScript对象

在使用JQuery开发时一般会把原生的js代码和JQuery代码混合在一起使用,但这两种对象有本质的区别,因此最好通过良好的命名方式来避免把两种对象变量搞混了,现在公认的一种比较好的方式是使用$作为JQuery变量的开头,

var $jquery = $("#abc"); //JQuery对象变量
var jquery = $jquery[0]; //原生js变量

这样就避免一些很明显的错误。