jquery优化

2026-05-02 12:25:37 191
分类:jquery

个人整理,不定期更新……

一、合理使用选择器

    1.最快的选择器:id选择器和元素标签选择器

在我们讨论选择多个元素的时候,我们真正需要知道的是DOM的遍历和循环才是性能低下的原因。为了尽量减少性能损失, 总是使用最近的父id去寻找。

在jQuery中最快的选择器是ID选择器,因为它直接来自于JavaScript的getElementById()方法。

在jQuery中第二快的选择器就是Tag选择器,而这是因为它直接映射到JavaScript的getElementsByTagName()方法。

    2.较慢的选择器:class选择器

在jQuery里Class选择器是较慢的一个选择器。Firefox、Safari、Chrome、Opera浏览器,都有原生方法getElementByClassName(),所以速度并不慢。但是,IE5-IE8都没有部署这个方法,所以这个选择器在IE中会相当慢。

用id或者tag来修饰class。

    3.最慢的选择器:伪类选择器和属性选择器

先来看例子。找出网页中所有的隐藏元素,就要用到伪类选择器:$(':hidden')

属性选择器的例子则是:$('[attribute=value]')

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

小节:不要过度使用jQuery。jQuery速度再快,也无法与原生的javascript方法相比。所以有原生方法可以使用的场合,尽量避免使用jQuery。以最简单的选择器为例,document.getElementById("foo")要比$("#foo")快10多倍。

二、做好缓存

通过定义一个全局容器保存jQuery结果对象,不要让相同的选择器在你的代码里出现多次。

为了区分普通的JavaScript对象和jQuery对象,可以在变量首字母前加上 $ 符号。

可以使用jQuery的链式操作加以改善,还可以使用子查询。

三、少改动DOM结构

    1.改动DOM结构开销很大,因此不要频繁使用.append()、.insertBefore()和.insetAfter()这样的方法。

如果要插入多个元素,就先把它们合并,然后再一次性插入。根据测试,合并插入比不合并插入,快了将近10倍。

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

四、尽量少生成jQuery对象

每当你使用一次选择器(比如$('#id')),就会生成一个jQuery对象。jQuery对象是一个很庞大的对象,带有很多属性和方法,会占用不少资源。所以,尽量少生成jQuery对象。

举例来说,许多jQuery方法都有两个版本,一个是供jQuery对象使用的版本,另一个是供jQuery函数使用的版本。下面两个例子,都是取出一个元素的文本,使用的都是text()方法。

你既可以使用针对jQuery对象的版本:

  var elem = $('#elem');

  elem.data(key,value);

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

  var elem = $('#elem');

  $.data(elem[0],key,value);

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

五、选择作用域链最短的方法

严格地说,这一条原则对所有Javascript编程都适用,而不仅仅针对jQuery。

我们知道,Javascript的变量采用链式作用域。读取变量的时候,先在当前作用域寻找该变量,如果找不到,就前往上一层的作用域寻找该变量。这样的设计,使得读取局部变量比读取全局变量快得多。

六、事件委托(又名:冒泡事件)

除非特别说明,每一个JavaScript事件(如click, mouseover 等)在DOM结构树上都会冒泡到它的父元素上。如果我们想让很多elements(nodes)调用同一个function这是非常有用的。取而代之的是 你可以只对它们的父级绑定一次,而且可以计算出是哪一个节点触发了事件,而不是绑定一个事件监听器到很多节点上这种效率低下的方式。例如,假如我们要开发 一个包含很多input的大型form,当input被选择的时候我们想绑定一个class name。像这样的帮定是效率低下的:

$('#myList li).bind('click', function(){
 
 $(this).addClass('clicked'); // do stuff
 
});

反而,我们应该在父级侦听click事件。

$('#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
 
 }
});

父节点担当着发报机的工作,可以在触发了事件的目标element上做一些工作。

七、压缩js