当前位置: 首页 > 后端技术 > PHP

jQuery效率提升建议

时间:2023-03-30 02:29:25 PHP

jQuery简洁通用的方法集,让码农从繁重的工作中解脱出来,也降低了入门javascript的门槛。对于对浏览器兼容性一无所知的初学者,几行代码就可以写出令人惊叹的特效。一篇文章在网上被大量转发。我不知道原始文章的作者。提高jQuery效率的建议非常科学。现将内容重新整理,转载。1.使用最新版本的jQueryjQuery的版本更新很快,你应该始终使用最新版本。因为新版本会提升性能,还有很多新功能。让我们来看看不同版本的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中,可以使用多个选择器来选择同一个网页元素。每个选择器的性能都不同,您应该了解它们的性能差异。最快的选择器:id选择器和元素标签选择器例如,下面的语句表现最好:$('#id')$('form')$('input')有时候,jQuery会自动调用浏览器的本地方法(比如getElementById()),所以它们的执行速度很快。较慢的选择器:类选择器$('.className')的性能取决于不同的浏览器。Firefox、Safari、Chrome、Opera浏览器都有原生方法getElementByClassName(),所以速度不慢。但是IE5-IE8都没有部署这个方法,所以这个selector在IE中会很慢,而且jQuery之前的更新对于IE8之前的版本是没有用的。最慢的选择器:伪类选择器和属性选择器我们先来看例子。要找到网页中的所有隐藏元素,需要使用伪类选择器:$(':hidden')属性选择器的一个例子是:$('[attribute=value]')这两个语句是最慢,因为浏览器没有它们的本地方法。但是,一些浏览器的新版本增加了querySelector()和querySelectorAll()方法,这将大大提高此类选择器的性能。最后是一张不同选择器的性能对比图。可以看到ID选择器遥遥领先,然后是标签选择器,第三是Class选择器,其他选择器都很慢。3、理解子元素和父元素的关系下面六个选择器从父元素中选择子元素。你知道哪个最快哪个最慢吗?$('.child',$parent)$parent.find('.child')$parent.children('.child')$('#parent>.child')$('#parent.child')$('.child',$('#parent'))我们一句一句的看。$('.child',$parent)语句表示给定一个DOM对象,从中选择一个子元素。jQuery会自动将这条语句转换为$.parent.find('child'),这会造成一定的性能损失。它比最快的形式慢5%-10%。$parent.find('.child')是最快的语句。.find()方法会调用浏览器的本地方法(getElementById、getElementByName、getElementByTagName等),因此速度更快。$parent.children('.child')语句在jQuery内部,会使用$.sibling()和javascript的nextSibling()方法逐一遍历节点。它比最快的形式慢大约50%。$('#parent>.child')jQuery在内部使用Sizzle引擎来处理各种选择器。Sizzle引擎的选择顺序是从右到左,所以这条语句先选择.child,然后一个一个过滤掉父元素#parent,这样比最快的形式慢了70%左右。$('#parent.child')语句与上一个相同。但是,前一种只选择直接孩子,这个可以选择多级孩子,所以速度较慢,比最快的形式慢了大约77%。$('.child',$('#parent'))jQuery在内部将此语句转换为$('#parent').find('.child'),这比最快的形式慢23%。所以,最好的选择是$parent.find('.child')。而且,由于在前面的操作中经常会产生$parent,所以jQuery会对其进行缓存,从而进一步加快了执行速度。4.不要过度使用jQuery无论jQuery有多快,都无法与原生的javascript方法相提并论。所以当有native方法可以使用的时候,尽量避免使用jQuery。请看下面的例子来绑定一个函数来处理a元素的点击事件:$('a').click(function(){alert($(this).attr('id'));});this这段代码的意思是,点击a元素后,弹出该元素的id属性。为了得到这个属性,jQuery必须连续调用两次,第一次是$(this),第二次是attr('id')。其实这个处理是完全没有必要的。更正确的写法是使用javascriptnative方法直接调用this.id。据测试,this.id的速度比$(this).attr('id')快20多倍。5、做好缓存,选择某个网页元素,这是一个非常昂贵的步骤。因此,选择器使用的次数越少越好,选择的结果尽可能缓存起来,以备日后重复使用。例如下面的写法不好:jQuery('#top').find('p.classA');jQuery('#top').find('p.classB');更好的写法是:varcached=jQuery('#top');cached.find('p.classA');cached.find('p.classB');据测试,缓存比不缓存快2-3倍。6.使用链式书写jQuery的一大特点就是允许使用链式书写。$('div').find('h3').eq(2).html('你好');当使用链式写法时,jQuery会自动缓存每一步的结果,所以比非链式写法更快。根据测试,链式写法比非链式写法(不带缓存)快25%左右。7、事件委托处理(EventDelegation)javascript事件模型采用“冒泡”模式,也就是说子元素的事件会一步步“冒泡”起来,成为父元素的事件。使用它,您可以大大简化事件的绑定。比如有一个表格(table元素)有100个格子(td元素),现在需要给每个格子绑定一个点击事件(click)。您需要执行以下命令100次吗?$("td").bind("点击",function(){$(this).toggleClass("点击");});答案是否定的,我们只需要将这个事件绑定到table元素即可,因为td元素发生点击事件后,该事件会“冒泡”到父元素table并被监听。因此,这个事件只需要在父元素上绑定一次,而不是在子元素上绑定100次,大大提高了性能。这称为事件的“委托处理”,即子元素“委托”父元素来处理事件。具体有两种写法。第一种是使用.delegate()方法:$("table").delegate("td","click",function(){$(this).toggleClass("click");});第二种.live()方法用到:$("table").each(function(){$("td",this).live("click",function(){$(this).toggleClass(“点击”);});});这两种写法基本是等价的。唯一的区别是.delegate()是在事件冒泡到指定的父元素时触发,而.live()是在事件冒泡到文档的根元素时触发,所以.delegate()比.live好()快一点。另外,这两个方法比传统的.bind()方法还有一个优势,就是对动态插入的元素也有效。.bind()只对现有的DOM元素有效,对动态插入的元素无效。据测试,委托处理比非委托处理快几十倍。在委托处理的情况下,.delegate()比.live()快约26%。8.对DOM结构的改动少改变DOM结构的代价非常大,所以不要频繁使用.append()、.insertBefore()和.insetAfter()等方法。如果要插入多个元素,先合并,然后一次性全部插入。根据测试,合并插入比未合并插入快近10倍。如果你想对一个DOM元素做大量的处理,你应该先用.detach()方法把这个元素从DOM中取出来,处理完后再插入回文档中。根据测试,使用.detach()方法比不使用快60%。如果你想在DOM元素上存储数据,不要这样写:varelem=$('#elem');elem.data(key,value);相反,写varelem=$('#elem');$.data(elem,key,value);据测试,后一种写法比前一种写法快近10倍。因为elem.data()方法是定义在jQuery函数的原型对象上,而$.data()方法是定义在jQuery函数上,所以调用时不是从复杂的jQuery对象中调用,所以速度是快多了。(参见下面的第10点。)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、小结我对jQuery对象方法和自身函数的运行速度进行了比较,分别对文中提到的文本和数据进行了测试。text测试结果不明显,$.text比objectmethodtext略有优势。由于对象数据会改变dom,所以速度会比jQuery函数数据慢很多。