如何调优jQuery的性能

这篇文章将为大家详细讲解有关如何调优jQuery的性能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

网站制作、成都网站设计服务团队是一支充满着热情的团队,执着、敏锐、追求更好,是创新互联的标准与要求,同时竭诚为客户提供服务是我们的理念。创新互联建站把每个网站当做一个产品来开发,精雕细琢,追求一名工匠心中的细致,我们更用心!

创建性能测试

关于性能测试的第一步是创建一个合适的性能测试。jQuery 以及其他 JavaScript 库在代码中扮演的最重要角色就是使用选择查找特定页面元素。我在最初的性能测试中就以这方面为重点。一个良好的性能测试应该真正地发挥 JavaScript 库的全部力量,用包含数千个页面元素的页面测试它。应该运行所有选择方法,让我看到哪个选择方法最快,哪个最慢。测试应该事先知道正确的答案,从而确定 JavaScript 库是否正确地执行选择方法。最后,应该显示所有结果,并附带所用的运行时间,让我能够在所有库之间进行比较。

我差点忽略了性能测试的最重要方面:它应该是免费的。毕竟这个系列文章的不成文规则就是相互利用彼此的成果,因此我继续发扬这种精神,在此使用一个现成的 JavaScript 库性能测试。这个测试称为 SlickSpeed Selectors Test(见 参考资料),它非常适合我的需求。它将 jQuery 1.2.6(撰写本文时的最新版本)与其他 4 个流行的 JavaScript 库(MooTools、Prototype、YUI 和 Dojo)进行比较。然后,它使用带有数千个页面元素的页面运行40个选择测试。换句话说,这是我所希望的最佳性能测试。我将在第一个性能测试分析中使用该测试。

对比JavaScript 库的性能

对于第一个性能测试,我使用的运行环境是 2.2 GHz 处理器、2 GB RAM 和 Firefox 3.0.3(非常重要)。我在该配置下运行 5 次测试,图 1 显示了 5 次运行的平均结果。

图 1. 性能测试 1 的结果

如何调优jQuery的性能

从第一次测试能够得出什么结论?现在我们仅关注总体结果,而不是每次测试。在获得一些总体结论之后,我将稍后在本文中关注每个测试。

◆  结论 1:YUI 慢到了极点!

对,与其他库相比,YUI 真的很慢。仔细查看每个测试,找出为什么这个库在选择元素组(例如 “p, a”)时非常慢。对于要求具有很好性能的页面而言,这个库是最差的选择。

◆  结论 2:Mootools、jQuery 和 Dojo 的运行时间几乎一样。

与其他两个库相比,这 3 个库是非常快的,并且 Dojo 是它们当中最快的,而 jQuery 是最慢的。但是从全局考虑,它们之间的速度是很接近的。

◆  结论 3:这些库之间的相对差别还是比较明显的。

度量最快时间/最慢时间以确定速度的相对差别,您可以看到相对差别为 332%。这个差别是比较大的,这表明使用 Firefox 时选择不同的 JavaScript 库会对性能有影响。

但是要记住,这些结论仅基于一个浏览器的结果。这是基于 Firefox 3.0.3 得出的结论。现在我们进入下一小节,我将在不同的浏览器上运行该测试。

在不同浏览器上的JavaScript 性能

面对不同浏览器运行 JavaScript 会得出的不同结果(性能和时间都不同),许多初级 Web 程序员觉得不可思议。尽管这对初级 Web 程序员而言是个挫折(他们担心要编写额外的代码来处理不同的浏览器),但是有经验的 Web 程序员在 Netscape 和 Internet Explorer 的早期就知道如何处理该问题。这也是使用 JavaScript 库的一个亮点,因为它们都谨慎处理许多或大部分浏览器差异。

JavaScript 速度差异的主要原因是每个浏览器都使用自己的 JavaScript 引擎。JavaScript 引擎是用于解析 JavaScript 并根据 Web 应用程序执行它的本机代码。因此,JavaScript 的执行速度与底层引擎直接相关。在最近几个月,许多浏览器公司越来越关注他们的浏览器的性能,这是有原因的。随着某些页面的 JavaScript 变得日益复杂,JavaScript 引擎的快慢能够影响 Web 应用程序的响应速度。因此,当 Google 和 Firefox 等公司谈论它们的 JavaScript 引擎时,它们就会谈及下一代引擎的速度要快 10 倍。这对 Web 应用程序而言是很重要的,因为底层 JavaScript 引擎的速度直接导致更复杂的 Web 应用程序的出现。

现在,您知道 JavaScript 引擎是 JavaScript 执行速度的一个因素,那么让我们在不同的浏览器上运行刚才在 Firefox 上运行的测试,并尝试找出不同的引擎对 JavaScript 性能的影响。记住,这个测试与我前面在 Firefox 上运行的测试是一样的,因此除了 JavaScript 引擎以外,其他所有东西都是相同的。图 2 显示了测试结果。

图 2. 性能测试 2 的结果

如何调优jQuery的性能

看完这些测试结果之后,您首先注意到的是在这些浏览器中运行得到的时间差很大。在 Chrome 1.0 上运行 jQuery 需要 168 毫秒,而在 IE6 上运行需要 1728 秒。这是难以置信的时间差!jQuery 选择方法在 IE6 上运行比在 Chrome 上运行慢 10 倍!现在,您知道为什么 Google 喜欢夸耀它的 JavaScript 引擎,以及为什么某些浏览器很少介绍自己的 JavaScript 引擎。这些差别还是比较大的。

您应该注意到,jQuery 在 Firefox 或一些其他浏览器上运行时速度排在第 3 位,而在另一些浏览器上排在第 1 位。事实上,这些结果表明,根据性能进行分类的话,这些库可以分为两组,而不管使用什么浏览器。Mootools、Dojo 和 jQuery 通常属于一个组别,而 Prototype 和 YUI 属于另一个组别,前一组要比后一组快得多。

性能测试结论

我觉得所有这些结论都需要专门花一个小节进行阐述,因为它们对 JavaScript 开发人员非常重要。我仍然尝试总结上面的性能结果,并且没有忘记本文是以 jQuery 为主题的。

◆ 结论 1:Mootools、jQuery 和 Dojo 在性能方面不分上下。

查看它们在所有 5 个浏览器上进行的测试,在求取平均值之后,您可以看到这 3 个库的性能几乎是一样的。(理想情况下,我们应该调查每个浏览器的市场份额。但是调整这些数字很难,因为使用 JavaScript 库的站点不一定由 “平均用户” 访问)。

图 3. 测试结果的平均值(Mootools、jQuery 和 Dojo)

如何调优jQuery的性能


◆ 结论 2:Prototype 和 YUI 的性能很慢。

看看这两个库在 5 个浏览器中的测试结果与 jQuery 的对比。在求取它们的平均值之后,您可以发现这两个库的性能差别有多大。它们在任意浏览器中平均比 jQuery 慢 300%。

图 4. 测试结果的平均值(jQuery、Prototype 和 YUI)

如何调优jQuery的性能


◆ 结论 3:如果对性能要求比较高时,选择 Mootools、jQuery 和 Dojo 之一获得的性能几乎一样。

根据以上的平均值,选择这 3 个库之一比选择另外两个库之一能够获得更多的性能优势。从在所有浏览器上运行得出的平均值看,它们的性能是相当的。因此,当您选择 JavaScript 库时,选择这 3 个库之一是不会错的。

◆ 结论 4:如果对性能要求比较高时,不要选择 Prototype 或 YUI。

如果要求 JavaScript 库具有较高的性能,或者打算创建一个大型的 JavaScript 项目,那么就不应该选择这两个库之一。这两个库的性能要比其他库逊色得多。

◆ 结论 5:浏览器对性能的影响是 JavaScript 库的 9 倍。

我认为这是本文所有结论中最重要的结论。您可以在特定情况下讨论哪个 JavaScript 库最快,但它最终的影响却是很小的!对于性能而言,浏览器的影响比库本身要大得多。回顾一下图 3 和图 4 的平均值,您可以看到 3 个最快的库中,最慢那个(Dojo)仅比最快那个(jQuery)慢 15%。只有 15%!然而,您看看 jQuery 在最快的浏览器(Chrome 1.0)和最慢的浏览器(IE6)上运行的速度差别,这个差别竟然达到 1000%!从这两个数字看,15% 对 1000% 而言是微不足道的。至此,关于 3 个较快的库中哪个是最快的争论可以停止了,因为它们对最终结果的影响是微乎其微的。

◆ 结论 6:如果 JavaScript 性能对 Web 应用程序很重要,并且您可以控制选择什么浏览器,那么就选择最快的浏览器!

在某些情况下,您可以控制使用什么浏览器访问站点。如果能够控制使用什么浏览器,那么您就是很幸运的。我就碰到这样幸运的项目。在这种情况下,如果您拥有一个复杂的 JavaScript 应用程序,或者您认为性能很重要,那么您就应该控制用户用于访问 Web 应用程序的浏览器。这些测试已经清楚地显示了浏览器的影响。如果您的 JavaScript 应用程序的访问量很大,那么您可以告诉用户,他们必须 使用 Chrome。

◆ 结论 7:如果您不能控制用户使用的浏览器,那么要首先考虑在 IE6 上的性能。

但是,在大部分情况下,我们都无法控制用户使用什么浏览器访问我们的站点。不过,很大一部分用户都使用 IE 6 浏览网页。到目前为止的测试中,这个浏览器的 JavaScript 引擎是最慢的。但是由于仍然有大量用户使用它,并且良好的 Web 设计需要 “适应最糟糕的情况”,这意味着您可以考虑根据 IE6 设计您的 JavaScript 应用程序。

jQuery 性能调优

本文的第二部分将讨论如何改进 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 搜索对比

如何调优jQuery的性能


这些测试是不同的,但它们得出的数据表明通过 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 += "";    }    $("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 += "";    }    $("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. 尽可能多地提供信息

如何调优jQuery的性能


考虑到底层 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     // 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. 缓存

在我的最后一个关于性能

// Imagine a function that hides all the div's with a class of "hideable"   // when a button is pressed.  These DIV's might reappear later when   // working with the page,  so the button can be pressed any number of   // times, and the DIV's that have reappeared  // will again be made to be hidden.   $("#ourHideButton").click(function(){     $(".hideable").hide();  });   // As you saw in the CLASS versus ID example, though, a search for   // CLASS is very inefficient  // If this button is pressed often, it could lead to a slow response  // Instead of the above example, you should write your code like this   var hideable;   $("#ourHideButton").click(function(){     if (hideable)         hideable.hide();     else        hideable = $(".hideable").hide();  });   // You can cache your search in a JavaScript variable and reuse it every time  // the button is pressed.  Because jQuery almost always returns the  // jQuery object, you can save it the first time it is called for future use

的示例代码中,将查看我在本系列的第一篇文章中提到的小部件(见 参考资料)。这个小部件是在表的左上角上的复选框,它允许您选择或取消选择该列上的所有复选框。这个小部件在电子邮件应用程序中非常常见,用于选择或取消选择所有消息。

清单 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 here   function 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();      });  }

关于性能的要点

使用 JavaScript 时,速度和性能绝对不是小问题。在现实中,创建 jQuery 的开发人员和处理浏览器内置 JavaScript 引擎的开发人员都非常关注性能问题。事实上,在最近 6 个月以来,浏览器开发的最重要问题就是 JavaScript 引擎的速度。浏览器开发者都致力于在下一年迅速提升 JavaScript 的执行性能,从而大大提高 jQuery 代码和 JavaScript 引擎的速度。来自这些 “速度之战” 的消息表明,提升 JavaScript 性能是大势所趋。领导 jQuery 项目的 John Resig 一直都在谈论他的最新 “Sizzle” 选择引擎。他从头编写了一个选择引擎,并声称初步结果表明它比 Firefox 要快 4 倍。这是巨大的速度提升!在我撰写本文的最后部分时,jQuery 1.3 已经发布,并且包含了 Sizzle 选择引擎。jQuery 声称,在所有浏览器上运行的总体结果表明选择引擎的 1.3 版本比 1.2.6 版本的快 49%。此外,1.3 发布版在 HTML 注入(向 DOM 添加新的元素)上改进了 6 倍,在函数定位上改进了 3 倍。在我完成本文时,很多人都更新到了最新的 jQuery 发布版,这是非常令人激动的!

影响 JavaScript 性能的另一个因素是浏览器,如前所述,它的影响是所选的库的 9 倍。Firefox 和 Chrome 在 “最快 JavaScript 引擎” 之战中各有胜负,而 Safari 的参与让竞争更加激烈。从我们上面的测试中,可以看到 Chrome 在 JavaScript 引擎性能方面远远超过 Firefox,但是 Firefox 3.1 将包含新的 Tracemonkey JavaScript 引擎,届时其速度将比当前的 JavaScript 引擎 3.0 快 20 至 40 倍(这是他们声称的,不是我的观点),真不可思议!

在未来一两年内,您将看到底层 JavaScript 引擎和 JavaScript 库的速度得到巨大改进,从而导致使用 JavaScript 的 Web 应用程序将变得更加复杂。

如果您正在决定是使用 JavaScript 库还是自己编写 JavaScript,那么需要考虑的另一件事情是处理和调试 JavaScript 库所需的全部工作。最近几年以来,有数百位用户一直在维护库中的每一个函数。您可能要忙到深夜,甚至筋疲力尽地编写自己的函数。您更相信谁呢?另外,即使您能编写出比 jQuery 库更快的代码,您是否想过使用 jQuery 库能够获得更多的优势?您是否为了辛苦地编写自己的代码而放弃使用非常便利的 jQuery 及其函数库?自己编写代码不仅需要大量时间,并且还会产生更多 bug,因此我还是建议使用现成的 jQuery 库。

我最后讨论的要点可能会让一些人沮丧,但是我们必须考虑编写这些 jQuery 库的程序员。他们当中的一些是最棒的,并且他们编写的超级优秀的代码(一般人不能编写这样出色的代码)都收入到这些库中。我承认自己远远不如编写 jQuery 库的程序员。因此,为何不利用他们的智慧?

关于如何调优jQuery的性能就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。


分享文章:如何调优jQuery的性能
当前链接:http://myzitong.com/article/gedssi.html