使用***选择器在使用JQuery时,可以使用多个选择器来选择同一个元素。各种方法的表现是不一样的,有时候相差会很大。常用的选择器如下:ID选择器$("#id")标签选择器$("td")类选择器$(".target")属性选择器$("td[target='target']")伪-classselector$("td:hidden")根据经验应该知道这5个选择器的性能依次下降,我们不妨做个测试看看它们的性能到底相差多少:测试html片段: 测试结果测试计划:执行每个脚本1w次,计算3次运行结果的平均值。计划IE6IE7IE8IE9chromefirefoxoperasafari$("#mytabletd.target")515056307802936914831102$("#mytable.target")532057809402976114132101$("#mytable").find("td.target")4840500012503879520573157$("#mytable").find(".target")500051501400226491306064$("#mytabletd[target=target]")16410176609404068916635120$("#mytabletd:hidden")250002672023750363863211233434569$("#target-td")630620310629281218$(".target")1031010790940207361814744document.getElementBy5t"10d"1-target(")516061152结语原生方法是最快的方法,如果可能,尽量使用原生的表现顺序:ID选择器>标签选择器>类选择器>属性选择器>伪类选择器ID(getElementById),标签选择器(getElementsByTagName)有对应的native方法,所以速度很快;类选择器除了IE5-IE8,几乎所有主流浏览器都有native方法(getElementsByClassName)。为了兼顾IE6、7的性能,and8,avoidUseglobalclassselectors;attribute和pseudo-classselectors很慢,如果没有必要尽量少用pseudo-classselectors和attributeselectors***针对模块中操作频率最高的元素进行练习用根元素设置id,然后缓存;对于没有id的元素检索,尽量使用路径最短的祖先元素id作为默认的搜索范围,使用纯类选择器或者标签选择器;尽量避免复杂的选择器以避免全局执行Find$("div.bizHelp");=>$("#container").find(".bizHelp");保证最短查询路径和最佳性能,参考文章***;avoidemptyresultsOperation对于编号为0的选择结果,JQuery会执行默认动作而不报错,影响程序性能varblank=$(".blank");//length=0A:blank.slideUp();B:blank.length&&blank.slideUp();测试结果测试说明:1000次执行,单位毫秒/ms,3次运行的平均值IE6IE7IE8IE9chromefirefoxoperasafariA611056101344488103194108155B00000000结论你应该避免对空对象进行操作;使用样式表来避免多次调整并将多种样式应用于一个对象。最好使用样式表来避免多次应用。varobj=$("#obj");A:obj.css("宽度",200);obj.css("高度",200);obj.css("背景":"#eee");B:obj.attr("style","width:200px;height:200px;background:#eee;");C:.css-operation{width:200px;height:200px;background:#eee;}obj.addClass("css-operation")测试结果测试说明:1000次执行时间,单位毫秒/ms,平均值三跑统计方案IE6IE7IE8IE9chromefirefoxoperasafariA259424861500501163222190191B100095354719079281586C84367240711121171631结论性能排序:C>B>A样式与JS分离方案性能最佳,适用于需要同时设置多种样式的场景;如果您只应用单一样式,可以考虑使用方案A来简化操作。样式多了几个,又不愿意新建一个css类,可以用B;#p#避免使用匿名函数大量的匿名函数会增加程序通过第三方软件调试、维护和性能测试的难度,所以应该尽量避免使用大量的匿名函数obj.click(function(){//dosomething...})=>>varclickHandler=function(){//dosomething...}obj.click(clickHandler)大循环效率更高遍历方式JQuery提供了$.fn.each()和$.each()来实现集合的遍历。另外也可以使用JS原生的for循环,while等实现迭代。应该是了解它们之间的性能差异:varlist=ul.find("li"),e;A:vari=list.length;while(i--){e=$(list[i])}B:list.each(function(){e=$(this);});C:$.each(list,function(){e=$(this);});测试结果测试说明:1w次执行耗时,单位为毫秒/ms,计算3次操作的平均值。方案IE6IE7IE8IE9chromefirefoxoperasafariA172219157303546B219234203414658C219234187523457结论一般来说,A>C>B方案A有25%左右的性能提升,但不稳定;在IE浏览器下B方案和C方案性能差不多,A方案有绝对优势;方案A在Chrome和firefox下性能不稳定;最佳实践是追求最佳性能,所以采用方案A;如果循环次数少,推荐使用方案C,比较稳定;首先使用本机属性。很多常用的属性,比如id、name等,都是浏览器原生实现的。在JQuery中,我们有时会使用$(this).attr("id")来获取它们的id,这种方法的效率相对于获取原生属性的效率来说是非常慢的$.each(list,function(){//Avarid=$(this).attr("id");//Bvarid=this.id;})测试结果测试说明:10万次执行,单位毫秒/ms,统计3次运行的平均值IE6IE7IE8IE9chromefirefoxoperasafariA6880703042201188157244133135B3103101502745173结论使用原生API可以大大提高性能***实践对于常用id等属性,使用原生属性代替attr获取;使用事件委托经常会遇到对列表中的所有元素都添加点击事件的业务场景。传统的方法是获取这个列表的JQuery对象:$("li"),然后添加点击事件:$("li").click(function(){})这种方法在数量多的时候会有严重的性能问题oflists比较大,应该值得关注。JQuery在很早的版本就引入了事件委托机制,可以大大减少添加事件监听器的消耗和内存消耗。测试1w条记录的列表:A:varlist=$("li");//length>1list.click(function(){})B:$("ul").delegate("li","click",function(){})测试结果测试说明:给1w个
