分类分类
关注+2011-01-21作者:清晨
本文将讨论如何改进 jQuery 代码的性能。前一部分表明选择 jQuery 作为 JavaScript 库指向了正确的性能方向。如果您正在阅读本文,您可能已经使用了 jQuery。但是底层库速度快并不意味着您编写的所有代码都是高质量的。如果您没有回过头来想想应该怎么做,使用 jQuery 仍然会编写出非常慢的代码。
这个部分介绍一些性能调优知识,以及改进 jQuery 代码速度的最佳实践技巧。
技巧 #1 - 尽可能多地通过 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 进行搜索时的测试结果(图 5)。
图 5. ID 搜索和 CLASS 搜索对比
这些测试是不同的,但它们得出的数据表明通过 ID 进行搜索比通过 CLASS 进行搜索快得多。这如何影响到 jQuery 代码?在编写搜索时,您要记住这些技巧:如果既可选择 CLASS 又可选择 ID,那么通常要选择 ID。如果需要在您的代码中搜索某些元素,一定要给它们分配 ID。
清单 1 显示了一个实际的 jQuery 测试,您可以在您的机器上运行它对此进行验证:
清单 1. CLASS 和 ID
$(document).ready(function() { console.info("Start Test"); var d = new Date(); console.info(d.getSeconds() + " " + d.getMilliseconds()); var testBody = ""; for (var i=0; i<1000; i++) { testBody += "<div class='testable"+i+"'>"; } $("body").append(testBody); for (var i=0; i<1000; i++) { $(".testable"+i); } var d = new Date(); console.info(d.getSeconds() + " " + d.getMilliseconds()); console.time("Start ID Test"); testBody = ""; for (var i=0; i<1000; i++) { testBody += "<div id='testable"+i+"'>"; } $("body").append(testBody); for (var i=0; i<1000; i++) { $("#testable"+i); } var d = new Date(); console.info(d.getSeconds() + " " + d.getMilliseconds()); console.info("End Test"); }); |
ID 测试耗时 218 毫秒,而 CLASS 测试耗时 19.9 秒!甚至在专门为该测试构建的简单页面上,ID 搜索也要比 CLASS 搜索快 100 倍!
技巧 #2 - 提供尽可能多的搜索信息
jQuery 提供如此多的页面元素搜索方法,有时您难以指出哪种方法是最好的。有一条经验是不会错的,即为搜索参数提供尽可能多的信息。因此,假如您正在搜索带有 “clickable” CLASS 的所有页面元素,如果您提前知道仅有DIV附带有 CLASS,那么就能提高搜索性能。所以,搜索 “div.clickable” 会更加快。图 6 显示了支持该技巧的结果。
图 6. 尽可能多地提供信息
考虑到底层 JavaScript 代码之后,这就不足为奇了。通过提供元素标记,与 CLASS 参数匹配的搜索元素数量将大大减少,从而将搜索性能提升至与本例中的 ID 搜索相当。
开发人员在编写 jQuery 选择方法时不能偷懒,尽管 jQuery 的简单让人产生偷懒的欲望。简单让您放松了警惕。搜索机制变得如此简单,让我们倾向于仅输入一条信息。然而,您应该总是尽可能多地输入信息,尤其是已知信息。清单 2 显示了一个很好的例子。
清单 2. 提供充足的信息
// Assume there are 50 of these in some giant form, and you need to validate// these fields before they are submitted, and there are hundreds of other// elements on the page as well<input type=text class="notBlank">// the "bad" way to validate these fields$(".notBlank").each(function(){ if ($(this).val()=="") $(this).addClass("error");});// the "good" way to validate these fields$("input.notBlank").each(function(){ if ($(this).val()=="") $(this).addClass("error");});// the "best" way to validate these fields$("input:text.notBlank").each(function(){ if ($(this).val()=="") $(this).addClass("error"); }); |
技巧 #3 - 缓存选择器
最后一个性能技巧利用了几乎所有 jQuery 选择器都返回 jQuery 对象这个特性。这意味着在理想的情况下,您仅需要运行选择器一次,并且能够轻松地将所有函数连接在一起,或缓存结果供以后使用。您也不要担心缓存,因为与总体可用内存相比,返回的对象是很小的。
清单 3 给出了一些关于如何利用缓存的例子。
清单 3. 缓存
在我的最后一个关于性能的示例代码中,将查看我在本系列的第一篇文章中提到的小部件。这个小部件是在表的左上角上的复选框,它允许您选择或取消选择该列上的所有复选框。这个小部件在电子邮件应用程序中非常常见,用于选择或取消选择所有消息。
清单 4. 性能改进
// Here is the code as I originally presented it in that article. Let's see// if we can improve the performance in any way from the things we learned herefunction selectAll(){ var checked = $("#selectall").attr("checked"); $(".selectable").each(function(){ var subChecked = $(this).attr("checked"); if (subChecked != checked) $(this).click(); });}// Here's the improved function. The search for the ID of "selectall" is// OK as-is, because we saw how fast the ID search is.// The search for the CLASS of "selectable" was not well-designed though,// because we saw a search by CLASS is very inefficient.// First step was improving the search by supplying as much information as we know.// We narrowed the search to only checkboxes with the CLASS of selectable.// This should improve our search// Further, we can cache this search because we will only need to perform it once// Finally, we can perform this search before the selectall checkbox is even// checked (when the page is finished loading), so that the search is completed// and cached before the user even uses it.// These 3 simple performance steps gave me a 200% increase in speed when tested// on a page with 200 rows of data.var selectable = $(":checkbox.selectable");function selectAll(){ var checked = $("#selectall").attr("checked"); selectable.each(function(){ var subChecked = $(this).attr("checked"); if (subChecked != checked) $(this).click(); });} |
相关文章
更多+相同厂商
热门推荐
点击查看更多
点击查看更多
点击查看更多
说两句网友评论