本文共 5144 字,大约阅读时间需要 17 分钟。
这个部分介绍一些性能调优知识,以及改进jQuery代码速度的最佳实践技巧。
技巧#1-尽可能多地通过ID进行搜索,而不是CLASS
图5. ID搜索和CLASS搜索对比
在jQuery代码中两种常见的搜索技术是通过元素的ID进行搜索和通过元素的CLASS进行搜索。在使用常规JavaScript的JavaScript库之前,通过ID查找页面元素还是相当简单的。可以使用getElementById()方法快速找到元素。但是如果没有JavaScript库,要查找CLASS会更加困难,在必要情况下,我们还通过在其ID中进行编码帮助查找。
使用jQuery时,搜索CLASS就像搜索页面上的ID一样简单,因此这两个搜索似乎是可互换的。然而实际情况并非如此。通过ID搜索比通过CLASS搜索要快得多。当通过ID进行搜索时,jQuery实际上仅使用内置的getElementById()方法,但通过CLASS进行搜索时必须遍历页面上的所有元素,以查找匹配项。很明显,当页面越大并且越复杂时,通过CLASS进行搜索会导致响应非常慢,而通过ID进行搜索不会随着页面变大而变慢。
前面运行的jQuery性能测试结果支持这一数据。让我们查看每个测试,看看需要注意jQuery代码的什么地方。在这个例子中,分别看看通过ID和CLASS进行搜索时的测试结果。
这些测试是不同的,但它们得出的数据表明通过ID进行搜索比通过CLASS进行搜索快得多。这如何影响到jQuery代码?在编写搜索时,您要记住这些技巧:如果既可选择CLASS又可选择ID,那么通常要选择ID。如果需要在您的代码中搜索某些元素,一定要给它们分配ID。清单1显示了一个实际的jQuery测试,您可以在您的机器上运行它对此进行验证:
$(document).ready(function(){ console.info("StartTest"); vard=newDate(); console.info(d.getSeconds()+""+d.getMilliseconds()); vartestBody=""; for(vari=0;i<1000;i++) { testBody+=""; } $("body").append(testBody); for(vari=0;i<1000;i++) { $(".testable"+i); } vard=newDate(); console.info(d.getSeconds()+""+d.getMilliseconds()); console.time("StartIDTest"); testBody=""; for(vari=0;i<1000;i++) { testBody+=" "; } $("body").append(testBody); for(vari=0;i<1000;i++) { $("#testable"+i); } vard=newDate(); console.info(d.getSeconds()+""+d.getMilliseconds()); console.info("EndTest"); });
ID测试耗时218毫秒,而CLASS测试耗时19.9秒!甚至在专门为该测试构建的简单页面上,ID搜索也要比CLASS搜索快100倍!
技巧#2-提供尽可能多的搜索信息
图6. 尽可能多地提供信息
jQuery提供如此多的页面元素搜索方法,有时您难以指出哪种方法是最好的。有一条经验是不会错的,即为搜索参数提供尽可能多的信息。因此,假如您正在搜索带有“clickable”CLASS的所有页面元素,如果您提前知道仅有DIV附带有CLASS,那么就能提高搜索性能。所以,搜索“div.clickable”会更加快。图6显示了支持该技巧的结果。
考虑到底层JavaScript代码之后,这就不足为奇了。通过提供元素标记,与CLASS参数匹配的搜索元素数量将大大减少,从而将搜索性能提升至与本例中的ID搜索相当。开发人员在编写jQuery选择方法时不能偷懒,尽管jQuery的简单让人产生偷懒的欲望。简单让您放松了警惕。搜索机制变得如此简单,让我们倾向于仅输入一条信息。然而,您应该总是尽可能多地输入信息,尤其是已知信息。清单2显示了一个很好的例子。
//Assumethereare50oftheseinsomegiantform,andyouneedtovalidate //thesefieldsbeforetheyaresubmitted,andtherearehundredsofother //elementsonthepageaswell//the"bad"waytovalidatethesefields $(".notBlank").each(function(){ if($(this).val()=="") $(this).addClass("error"); }); //the"good"waytovalidatethesefields $("input.notBlank").each(function(){ if($(this).val()=="") $(this).addClass("error"); }); //the"best"waytovalidatethesefields $("input:text.notBlank").each(function(){ if($(this).val()=="") $(this).addClass("error"); });
技巧#3-缓存选择器
最后一个性能技巧利用了几乎所有jQuery选择器都返回jQuery对象这个特性。这意味着在理想的情况下,您仅需要运行选择器一次,并且能够轻松地将所有函数连接在一起,或缓存结果供以后使用。您也不要担心缓存,因为与总体可用内存相比,返回的对象是很小的。清单3给出了一些关于如何利用缓存的例子。
//Imagineafunctionthathidesallthediv'swithaclassof"hideable" //whenabuttonispressed.TheseDIV'smightreappearlaterwhen //workingwiththepage,sothebuttoncanbepressedanynumberof //times,andtheDIV'sthathavereappeared //willagainbemadetobehidden. $("#ourHideButton").click(function(){ $(".hideable").hide(); }); //AsyousawintheCLASSversusIDexample,though,asearchfor //CLASSisveryinefficient //Ifthisbuttonispressedoften,itcouldleadtoaslowresponse //Insteadoftheaboveexample,youshouldwriteyourcodelikethis varhideable; $("#ourHideButton").click(function(){ if(hideable) hideable.hide(); else hideable=$(".hideable").hide(); }); //YoucancacheyoursearchinaJavaScriptvariableandreuseiteverytime //thebuttonispressed.BecausejQueryalmostalwaysreturnsthe //jQueryobject,youcansaveitthefirsttimeitiscalledforfutureuse
在我的最后一个关于性能的示例代码中,将查看我在本系列的第一篇文章中提到的小部件(见参考资料)。这个小部件是在表的左上角上的复选框,它允许您选择或取消选择该列上的所有复选框。这个小部件在电子邮件应用程序中非常常见,用于选择或取消选择所有消息。
//HereisthecodeasIoriginallypresenteditinthatarticle.Let'ssee //ifwecanimprovetheperformanceinanywayfromthethingswelearnedhere functionselectAll() { varchecked=$("#selectall").attr("checked"); $(".selectable").each(function(){ varsubChecked=$(this).attr("checked"); if(subChecked!=checked) $(this).click(); }); } //Here'stheimprovedfunction.ThesearchfortheIDof"selectall"is //OKas-is,becausewesawhowfasttheIDsearchis. //ThesearchfortheCLASSof"selectable"wasnotwell-designedthough, //becausewesawasearchbyCLASSisveryinefficient. //Firststepwasimprovingthesearchbysupplyingasmuchinformationasweknow. //WenarrowedthesearchtoonlycheckboxeswiththeCLASSofselectable. //Thisshouldimproveoursearch //Further,wecancachethissearchbecausewewillonlyneedtoperformitonce //Finally,wecanperformthissearchbeforetheselectallcheckboxiseven //checked(whenthepageisfinishedloading),sothatthesearchiscompleted //andcachedbeforetheuserevenusesit. //These3simpleperformancestepsgavemea200%increaseinspeedwhentested //onapagewith200rowsofdata. varselectable=$(":checkbox.selectable"); functionselectAll() { varchecked=$("#selectall").attr("checked"); selectable.each(function(){ varsubChecked=$(this).attr("checked"); if(subChecked!=checked) $(this).click(); }); }
转载地址:http://ijebi.baihongyu.com/