我创建了一个jQuery插件来修改我的导航。不幸的是,我必须访问和修改几乎所有子元素,例如<ul>
,<li>
,<a>
等等。那些元素需要一到四次。
我应该将它们全部存储在变量中,还是应该在需要时访问$('.my-nav').find('li')
或$('.my-nav').find('li')
?
对于25行代码,有5个变量似乎是浪费内存。 但我不知道这是否是一个可以接受的权衡,以获得更高的性能。
我创建了一个小提琴来说明其含义:http://jsfiddle.net/Yj35Q/2/
答案 0 :(得分:8)
缓存节点始终是一种好习惯。您也可以使用http://jsperf.com/
对自己进行基准测试除非存储大量的DOM树或其他内容,否则您不必担心存储空间变量需要多少。与JS引擎定位节点所需的工作量相关性更为相关。
修改强>
甚至更好,你可以找到其他人已经创建的现有测试用例
http://jsperf.com/ns-jq-cached/4
答案 1 :(得分:3)
无论你是否使用jQuery,在适当的时候缓存你的DOM元素当然是明智的。
但这个问题让我想到也许我们应该有一个插件来帮助解决这个问题。我四处搜寻,找不到一个。
所以我写的很快。这是一个lazy loading jQuery selector ......
(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
根据jfriend00的建议,当你不是简单地传递一个字符串时,它会return $.apply(this, arguments)
。
答案 2 :(得分:2)
在同一个函数中,我会将DOM搜索的结果缓存在局部变量中,因此我不必在同一个函数中多次执行相同的DOM搜索。对于大多数函数来说,这不是必需的,但是只在函数期间将结果放在局部变量中是容易和安全的,所以我认为这是一个好习惯。
我通常不会将DOM节点缓存到全局变量中,因为我试图避免使用全局变量,并且在特定函数需要时检索DOM节点很少会出现性能问题。避免在全局变量中使用DOM引用的另一个原因是,如果某个特定DOM节点从DOM中删除并且您打算对其进行垃圾回收,如果在全局变量中有对它的引用,那么DOM节点将不会垃圾收集,可能导致内存泄漏。
在某些情况下,我反复查找同一个DOM节点(比如在计时器上),我将DOM节点缓存到函数闭包中的非全局变量中,然后在本地使用该变量。但是,我发现需要这种情况很少见。