`

jQuery 的运行速度优化

 
阅读更多

主要参考了Addy Osmani的PPT《提高jQuery性能的诀窍》(jQuery Proven Performance Tips And Tricks)。他是jQuery开发团队的成员,具有一定的权威性,提出的结论都有测试数据支持,非常有价值。

 

1. 使用最新版本的jQuery
jQuery的版本更新很快,你应该总是使用最新的版本。因为新版本会改进性能,还有很多新功能。
下面就来看看,不同版本的jQuery性能差异有多大。这里是三条最常见的jQuery选择语句:

$('.elem')
$('.elem', context)
context.find('.elem')

 

我们用1.4.2、1.4.4、1.6.2三个版本的jQuery测试,看看浏览器在1秒内能够执行多少次。结果如下:

 

可以看到,1.6.2版本的运行次数,远远超过两个老版本。尤其是第一条语句,性能有数倍的提高。
其他语句的测试,比如.attr("value")和.val(),也是新版本的jQuery表现好于老版本。

 

2. 用对选择器
在jQuery中,你可以用多种选择器,选择同一个网页元素。每种选择器的性能是不一样的,你应该了解它们的性能差异。
(1)最快的选择器:id选择器和元素标签选择器
举例来说,下面的语句性能最佳:

$('#id')
$('form')
$('input')

 

遇到这些选择器的时候,jQuery内部会自动调用浏览器的原生方法(比如getElementById()),所以它们的执行速度快。

 

(2)较慢的选择器:class选择器
$('.className')的性能,取决于不同的浏览器。
Firefox、Safari、Chrome、Opera浏览器,都有原生方法getElementByClassName(),所以速度并不慢。但是,IE5-IE8都没有部署这个方法,所以这个选择器在IE中会相当慢。


(3)最慢的选择器:伪类选择器和属性选择器
先来看例子。找出网页中所有的隐藏元素,就要用到伪类选择器:

$(':hidden')

 

属性选择器的例子则是:

$('[attribute=value]')

 

这两种语句是最慢的,因为浏览器没有针对它们的原生方法。但是,一些浏览器的新版本,增加了querySelector()和querySelectorAll()方法,因此会使这类选择器的性能有大幅提高。
最后是不同选择器的性能比较图。

 

可以看到,ID选择器遥遥领先,然后是标签选择器,第三是Class选择器,其他选择器都非常慢。

 

3. 理解子元素和父元素的关系
下面六个选择器,都是从父元素中选择子元素。你知道哪个速度最快,哪个速度最慢吗?

$('.child', $parent)
$parent.find('.child')
$parent.children('.child')
$('#parent > .child')
$('#parent .child')
$('.child', $('#parent'))

 

我们一句句来看。
(1) $('.child', $parent)
这条语句的意思是,给定一个DOM对象,然后从中选择一个子元素。jQuery会自动把这条语句转成$.parent.find('child'),这会导致一定的性能损失。它比最快的形式慢了5%-10%。

 

(2) $parent.find('.child')
这条是最快的语句。.find()方法会调用浏览器的原生方法(getElementById,getElementByName,getElementByTagName等等),所以速度较快。

 

(3) $parent.children('.child')
这条语句在jQuery内部,会使用$.sibling()和javascript的nextSibling()方法,一个个遍历节点。它比最快的形式大约慢50%。

 

(4) $('#parent > .child')
jQuery内部使用Sizzle引擎,处理各种选择器。Sizzle引擎的选择顺序是从右到左,所以这条语句是先选.child,然后再一个个过滤出父元素#parent,这导致它比最快的形式大约慢70%。

 

(5) $('#parent .child')
这条语句与上一条是同样的情况。但是,上一条只选择直接的子元素,这一条可以于选择多级子元素,所以它的速度更慢,大概比最快的形式慢了77%。

 

(6) $('.child', $('#parent'))
jQuery内部会将这条语句转成$('#parent').find('.child'),比最快的形式慢了23%。
所以,最佳选择是$parent.find('.child')。而且,由于$parent往往在前面的操作已经生成,jQuery会进行缓存,所以进一步加快了执行速度。
具体的例子和比较结果,请看这里。

 

4. 不要过度使用jQuery
jQuery速度再快,也无法与原生的javascript方法相比。所以有原生方法可以使用的场合,尽量避免使用jQuery。
以最简单的选择器为例,document.getElementById("foo")要比$("#foo")快10多倍。
再来看一个例子,为a元素绑定一个处理点击事件的函数:

$('a').click(function(){
	alert($(this).attr('id'));
});

 

这段代码的意思是,点击a元素后,弹出该元素的id属性。为了获取这个属性,必须连续两次调用jQuery,第一次是$(this),第二次是attr('id')。
事实上,这种处理完全不必要。更正确的写法是,直接采用javascript原生方法,调用this.id:

$('a').click(function(){
	alert(this.id);
});

 

根据测试,this.id的速度比$(this).attr('id')快了20多倍。

 

5. 做好缓存
选中某一个网页元素,是开销很大的步骤。所以,使用选择器的次数应该越少越好,并且尽可能缓存选中的结果,便于以后反复使用。
比如,下面这样的写法就是糟糕的写法:

jQuery('#top').find('p.classA');
jQuery('#top').find('p.classB');

 

更好的写法是:

var cached = jQuery('#top');
cached.find('p.classA');
cached.find('p.classB');

 

根据测试,缓存比不缓存,快了2-3倍。

 

6. 使用链式写法
jQuery的一大特点,就是允许使用链式写法。

$('div').find('h3').eq(2).html('Hello');

 
采用链式写法时,jQuery自动缓存每一步的结果,因此比非链式写法要快。根据测试,链式写法比(不使用缓存的)非链式写法,大约快了25%。

 

 

7. 事件的委托处理(Event Delegation)
javascript的事件模型,采用"冒泡"模式,也就是说,子元素的事件会逐级向上"冒泡",成为父元素的事件。
利用这一点,可以大大简化事件的绑定。比如,有一个表格(table元素),里面有100个格子(td元素),现在要求在每个格子上面绑定一个点击事件(click),请问是否需要将下面的命令执行100次?

$("td").on("click", function(){
	$(this).toggleClass("click");
});

 

回答是不需要,我们只要把这个事件绑定在table元素上面就可以了,因为td元素发生点击事件之后,这个事件会"冒泡"到父元素table上面,从而被监听到。
因此,这个事件只需要在父元素绑定1次即可,而不需要在子元素上绑定100次,从而大大提高性能。这就叫事件的"委托处理",也就是子元素"委托"父元素处理这个事件。

$("table").on("click", "td", function(){
	$(this).toggleClass("click");
});

 

更好的写法,则是把事件绑定在document对象上面。

$(document).on("click", "td", function(){
	$(this).toggleClass("click");
});

 

如果要取消事件的绑定,就使用off()方法。

$(document).off("click", "td");

 

8. 少改动DOM结构
(1)改动DOM结构开销很大,因此不要频繁使用.append()、.insertBefore()和.insetAfter()这样的方法。
如果要插入多个元素,就先把它们合并,然后再一次性插入。根据测试,合并插入比不合并插入,快了将近10倍。

 

(2)如果你要对一个DOM元素进行大量处理,应该先用.detach()方法,把这个元素从DOM中取出来,处理完毕以后,再重新插回文档。根据测试,使用.detach()方法比不使用时,快了60%。

 

(3)如果你要在DOM元素上储存数据,不要写成下面这样

var elem = $('#elem');
elem.data(key,value);

 

而要写成

var elem = $('#elem');
$.data(elem[0],key,value);

根据测试,后一种写法要比前一种写法,快了将近10倍。因为elem.data()方法是定义在jQuery函数的prototype对象上面的,而$.data()方法是定义jQuery函数上面的,调用的时候不从复杂的jQuery对象上调用,所以速度快得多。(此处可以参阅下面第10点。)

 

(4)插入html代码的时候,浏览器原生的innterHTML()方法比jQuery对象的html()更快。

 

9. 正确处理循环

循环总是一种比较耗时的操作,如果可以使用复杂的选择器直接选中元素,就不要使用循环,去一个个辨认元素。
javascript原生循环方法for和while,要比jQuery的.each()方法快,应该优先使用原生

 

10. 尽量少生成jQuery对象
每当你使用一次选择器(比如$('#id')),就会生成一个jQuery对象。jQuery对象是一个很庞大的对象,带有很多属性和方法,会占用不少资源。所以,尽量少生成jQuery对象。
举例来说,许多jQuery方法都有两个版本,一个是供jQuery对象使用的版本,另一个是供jQuery函数使用的版本。下面两个例子,都是取出一个元素的文本,使用的都是text()方法。
你既可以使用针对jQuery对象的版本:

var $text = $("#text");
var $ts = $text.text();

 

也可以使用针对jQuery函数的版本:

var $text = $("#text");
var $ts = $.text($text);

 

由于后一种针对jQuery函数的版本不通过jQuery对象操作,所以相对开销较小,速度比较快。

 

11. 选择作用域链最短的方法
严格地说,这一条原则对所有Javascript编程都适用,而不仅仅针对jQuery。
我们知道,Javascript的变量采用链式作用域。读取变量的时候,先在当前作用域寻找该变量,如果找不到,就前往上一层的作用域寻找该变量。这样的设计,使得读取局部变量比读取全局变量快得多。
请看下面两段代码,第一段代码是读取全局变量:

var a = 0;
function x(){
	a += 1;
}

 

第二段代码是读取局部变量:

function y(){
	var a = 0;
	a += 1;
}

 

第二段代码读取变量a的时候,不用前往上一层作用域,所以要比第一段代码快五六倍。
同理,在调用对象方法的时候,closure模式要比prototype模式更快。
prototype模式:

var X = function(name){ this.name = name; }
X.prototype.get_name = function() { return this.name; };

 

closure模式:

var Y = function(name) {
var y = { name: name };
	return { 'get_name': function() { return y.name; } };
};

 

同样是get_name()方法,closure模式更快。

 

12. 使用Pub/Sub模式管理事件
当发生某个事件后,如果要连续执行多个操作,最好不要写成下面这样:

function doSomthing{
	doSomethingElse();
	doOneMoreThing();
}

 

而要改用事件触发的形式:

function doSomething{
	$.trigger("DO_SOMETHING_DONE");
}
$(document).on("DO_SOMETHING_DONE", function(){
	doSomethingElse(); }
);

 

还可以考虑使用deferred对象。

function doSomething(){
    var dfd = new $.Deferred();
    //Do something async, then... 
    //dfd.resolve();
    return dfd.promise();
}
function doSomethingElse(){
	$.when(doSomething()).then(//The next thing);
}

 

 

 

  • 大小: 7 KB
  • 大小: 7.7 KB
分享到:
评论

相关推荐

    jquery性能优化高级技巧

    随之而来的就是在某些低端浏览器或者低端电脑上运行速度缓慢,甚至无法运行等问题。 因此我们有必要对我们自己书写的jquery代码进行优化,以达到更快捷、更流畅的运行效果。 jquery性能优化高级技巧,下面主要从七个...

    JQuery性能的优化大全

    ### JQuery性能优化大全 #### 一、引言 在Web开发中,JQuery因其轻量级、易用性以及强大的功能而备受开发者喜爱。然而,随着应用规模的扩大和技术的发展,提升代码执行效率成为了不可忽视的重点。本文将详细介绍几...

    jquery新手入门 简化js代码 运行速度更快

    **jQuery新手入门 简化JS代码 运行速度更快** 在编程领域,JavaScript(简称JS)是一种广泛使用的客户端脚本语言,常用于网页交互和动态效果的实现。然而,对于初学者而言,纯JavaScript的代码可能会显得复杂且难以...

    关于JQUERY性能的优化

    通过上述策略,开发者可以有效地提升jQuery代码的运行效率,从而提供更快的网页加载速度和更流畅的用户体验。不过,优化并非一蹴而就,需根据项目需求和具体情况进行调整。在实际工作中,持续学习和实践,结合性能...

    jQuery 2.1.4 运行包

    总的来说,jQuery 2.1.4运行包是开发人员构建交互性强、响应速度快的现代网页的重要工具。它的出现极大地降低了JavaScript编程的门槛,提高了开发效率。对于任何使用JavaScript进行Web开发的人来说,理解并熟练运用...

    JQuery性能优化指南

    然而,随着网页复杂性的增加,优化jQuery代码以提高性能变得至关重要。本指南将深入探讨如何通过一系列策略提升jQuery项目的性能,使用户体验更加流畅。 一、选择器优化 1. 使用ID选择器:jQuery中的`$("#id")`是最...

    jQuery性能优化指南

    本篇指南将深入探讨如何在使用jQuery时进行性能优化,确保你的网页运行流畅,用户得到更好的体验。 一、选择器优化 1. 避免使用通用选择器(如*,$,):这些选择器会遍历整个DOM树,消耗大量时间。 2. 使用ID选择器...

    Jquery性能优化指南

    在进行jQuery性能优化时,有几个关键点可以帮助提升代码运行效率,从而提高网页的加载速度和用户体验。以下是对这些优化策略的详细解释: 1. **总是从 ID 选择器开始继承**: ID选择器是最高效的,因为它直接对应...

    jQuery 性能优化手册 推荐

    《jQuery性能优化手册》是一份指导开发者提升...以上这些优化技巧能够帮助开发者编写出运行更快、资源消耗更少的jQuery代码,从而提升网页的整体性能。在实际开发中,应结合具体场景灵活应用,以达到最佳的优化效果。

    jquery mobile 1.4.2 和 jquery 1.8.3

    在jQuery Mobile 1.4.2中,我们可以看到一系列CSS文件,这些文件都是为了实现移动优化的界面样式和图标显示。例如: 1. `jquery.mobile-1.4.2.css` 是主样式表,包含了所有基本的样式规则,用于构建jQuery Mobile的...

    jquery-3.0.0.js 、jquery-3.0.0.min.js 【官方jquery包 js】

    在本篇文章中,我们将深入探讨jQuery 3.0.0版本,包括它的核心特性、优化的min.js版本以及在实际项目中的应用。 一、jQuery 3.0.0的核心特性 1. 兼容性:jQuery 3.0.0对浏览器的兼容性进行了全面升级,支持现代...

    jquery-1.9.1.js 、jquery-1.9.1.min.js 【官方jquery包 js】

    `jquery-1.9.1.js`是未压缩的源代码版本,便于开发者阅读、调试和学习,而`jquery-1.9.1.min.js`是经过压缩和优化后的版本,体积更小,适用于生产环境,以提高页面加载速度。 jQuery 1.9.1版本是一个重要的里程碑,...

    Jquery-1.11.3版本 jquery-1.11.3.rar

    这使得在处理大量元素时,jQuery的运行速度得到了提升,减少了对浏览器资源的消耗。 3. **兼容性** jQuery 1.11.x系列致力于保持与旧版浏览器的兼容性,包括IE6/7/8等。1.11.3版本确保了在这些浏览器上能正常工作...

    jquery1.4 jquery,jquery-1.4,jquery1.4,最新jquery.js,jquery-1.4.min.js

    1. **代码优化**:jQuery 1.4对内部代码进行了大量优化,提高了运行效率。特别是对于DOM操作,如元素选择和操作,性能显著提升。 2. **更小的文件大小**:`jquery-1.4.min.js`是压缩后的版本,它通过删除注释、多余...

    jquery-1.12.4.zip下载

    在1.12.4版本中,jQuery团队已经对之前版本的各种问题进行了修复和优化,保证了其在各种浏览器环境下的稳定运行。这个版本支持包括IE6在内的老版本浏览器,这在当今许多仍然需要照顾到老浏览器的项目中显得尤为重要...

    jquery-2.0.3.js和jquery-2.0.3.min.js

    对于现代浏览器来说,jQuery 2.0.3的运行速度更快,体积更小,更适合高性能的应用场景。 在jQuery 2.0.3中,主要包含以下关键特性: 1. **选择器增强**:jQuery 2.0.3支持CSS3选择器,使得开发者可以通过更复杂的...

    jquery-1.11.3.js和jquery-migrate-1.2.1 正式版

    在实际应用中,当你的项目依赖于1.11.3之前版本的jQuery特性时,可以先引入jQuery 1.11.3,然后加入jQuery Migrate 1.2.1,这样既能利用新版本的优化,又能确保旧代码的正常运行。同时,Migrate插件还会在控制台输出...

    jquery-1.11.3.js 、jquery-1.11.3.min.js 【官方jquery包 js】

    jQuery 1.11.3在性能上做了优化,例如使用Sizzle选择器引擎提升选择元素的速度,以及缓存查找结果以减少重复查询,这些改进使代码在大型项目中依然保持高效运行。 总的来说,jQuery 1.11.3是前端开发的重要工具,...

    jquery-migrate3.4版本

    虽然现代浏览器通常能够很好地处理新的jQuery版本,但jQuery Migrate 3.4.0仍然关注于对老式浏览器的支持,确保代码在这些环境中仍能正常运行。 5. **最佳实践**: 使用jQuery Migrate 3.4.0时,应结合代码审计来...

Global site tag (gtag.js) - Google Analytics