6

有很多关于缓存 jQuery 对象的问题,但我找不到一个询问 jQuery 对象可以并且应该被缓存的确切位置。我有一个网页,其中包含一个带有一堆函数的 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 对象,还是应该只在函数级别缓存?

4

3 回答 3

8

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

进一步的几点:

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

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

$(function(){

      var $nameInput = $('#name_input');

      $('body').data({ nameInput: $nameInput });

});

然后使用以下命令访问它:

function myFunctionOne() {

    var $nameInput = $('body').data('nameInput');
}
于 2013-02-19T21:52:23.560 回答
-1

这段代码会很好地混淆。您可以在 _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();
});
于 2013-12-10T00:55:15.397 回答