我应该在什么级别缓存jQuery DOM查询的结果?

有很多问题要求缓存jQuery对象,但我找不到一个询问jQuery对象可以和应该缓存的位置。 我有一个网页,其中包含一个包含一系列function的JavaScript文件,如下所示。

$(document).ready(function () { // do some setup }); /* function queries the DOM with the same selector multiple times without caching */ function myFunctionOne() { $('#name_input').css("border","1px solid #ccc"); $('#name_input').val(someValue); } /* function uses cached object from a single query */ function myFunctionTwo() { var nameInput = $('#name_input') nameInput.css("border","1px solid #ccc"); nameInput.val(someValue); // do some other stuff with cached selector } 

myFunctionOne我低效地查询DOM两次,而在myFunctionTwo我查询DOM一次,将结果缓存在局部变量中,然后使用该变量。 我知道myFunctionTwo中的方法更有效但我不确定我应该在哪里实际缓存这些对象。 在那一刻我在方法级别缓存对象,但我想知道我是否可以实际缓存它在更高级别,然后在多个函数中使用它。 这样我只会查询一次DOM,然后在该文件的所有函数中重用结果。 我建议的一个例子如下所示。

 $(document).ready(function () { // do some setup var nameInput = $('#name_input') }); /* function uses cached query result from .ready function above */ function myFunctionOne() { nameInput .css("border","1px solid #ccc"); nameInput .val(someValue); } /* function uses cached query result from .ready function above */ function myFunctionTwo() { nameInput.val(someValue); // do some other stuff with cached selector } 

这种方法是否合理还是有更好的方法吗? 也许使用.ready函数是一个不好的地方进行这种设置,因为它会减慢页面加载? 是否有另一种方法可以在对象级别缓存jQuery对象,还是只应在function级别缓存它们?

一如既往地在这些问题中,不要过早优化。 在这种情况下,这意味着在发现性能问题之前不要使用任何缓存。 如果您的目标客户使用低规格的计算机或移动设备,这意味着您需要自己在低规格硬件上进行测试,以便识别此类问题。 我强烈建议您在尝试通过添加缓存来提高速度之前先明确一点。

还有一些要点:

  • 如果您使用的是使用ID的选择器,它应该很快,因为它将在幕后使用getElementById ,因此不需要缓存。
  • 使用方法链而不是缓存,它只使用一次选择器
  • 如果确实实现了缓存,请先在本地执行。 方法之间的缓存在代码复杂性方面比本地缓存花费更多。
  • 使用.ready很好。 它在加载DOM后运行,是完成设置任务的正确位置。

一种方法是将选择器存储在$.cache

 $(function(){ var $nameInput = $('#name_input'); $('body').data({ nameInput: $nameInput }); }); 

然后使用以下方式访问它:

 function myFunctionOne() { var $nameInput = $('body').data('nameInput'); } 

这段代码会很好地混淆。 您可以在_initControls中添加任意数量的控件,并在以后的整个脚本块中使用它们。 如果您希望它对所有脚本块都是全局的,那么将_initControls函数移出jQuery onreadystate函数。

  $(function () { "use strict"; var _controls = {}, _init = function () { _initControls(); _updateData("Hello"); }, _initControls = function () { _controls.nameInput = $("#name_input"); }, _updateData = function (value) { var nameInput = _controls.nameInput; nameInput.css("border", "1px solid #ccc"); nameInput.val(value); }; _init(); });