7

我创建了一个 jQuery 插件来修改我的导航。不幸的是,我必须访问和修改几乎所有的子元素,例如<ul>,等等。然后需要这些元素一到四次。<li><a>

我应该将它们全部存储在变量中还是应该像访问它们一样$('.my-nav').find('li')$('.my-nav').find('li')在需要时访问它们?

为 25 行代码设置 5 个变量似乎是在浪费内存。但我不知道这是否是一个可以接受的权衡以获得更高的性能。

我创建了一个小提琴来说明什么意思:http: //jsfiddle.net/Yj35Q/2/

4

3 回答 3

8

缓存节点总是好的做法。您还可以使用http://jsperf.com/对自己进行基准测试

除非您要存储大量 DOM 树或其他东西,否则您实际上不需要担心变量需要多少存储空间。更相关的是 JS 引擎必须做的工作量来定位节点。

编辑
甚至更好,您可以找到其他人已经创建的现有测试用例
http://jsperf.com/ns-jq-cached/4

于 2012-05-07T21:43:48.267 回答
4

无论您是否使用 jQuery,在适当的地方缓存 DOM 元素当然是明智的。

但是这个问题让我想到也许我们应该有一个插件来帮助解决这个问题。我四处寻找,一个也找不到。

所以我很快就写了一篇。这是一个延迟加载的 jQuery 选择器......

(function($){
    var cachedObjects = new Array();

    $.lazy = function(selector) {
        if (typeof selector != "string" || arguments.length > 1) 
            return $.apply(this, arguments);

        var o = cachedObjects[selector];
        if (o == undefined)
        {
            o = $(selector);
            cachedObjects[selector] = o;
        }

        return o;
    };
})(jQuery);

你会这样使用它...

$.lazy('.my-nav').show();

如果我忽略了什么,请告诉我。但我相信只要您选择的元素是静态的并且永远不会动态添加或删除,这将是很好的选择。

更新

我已经更改了代码以提高效率。而且,我已经return $(selector)在选择器不是字符串的时候添加了一行。因此,只有在选择器为字符串时,缓存才能起作用。

更新#2

现在return $.apply(this, arguments),根据 jfriend00 的建议,您不只是简单地传递一个字符串。

于 2012-05-07T22:50:29.353 回答
2

在同一个函数中,我会将 DOM 搜索的结果缓存在一个局部变量中,这样我就不必在同一个函数中多次执行同一个 DOM 搜索。对于大多数函数来说,这不是必需的,但是仅在函数执行期间将结果放入局部变量中既简单又安全,所以我认为这是一个好习惯。

我通常不会仅仅因为我试图避免使用全局变量而将 DOM 节点缓存到全局变量中,而且在需要特定功能时检索 DOM 节点很少是性能问题。避免在全局变量中引用 DOM 的另一个原因是,如果某个特定的 DOM 节点从 DOM 中删除并且您打算将其作为垃圾回收,如果在全局变量中有对它的引用,则该 DOM 节点将不会被垃圾收集并可能导致内存泄漏。

在某些情况下,我会反复查找同一个 DOM 节点(例如在计时器上),我会将 DOM 节点缓存到函数闭包中的非全局变量中,然后在本地使用该变量。但是,我发现这种情况很少见。

于 2012-05-07T21:52:39.767 回答