全局JQuery Selector缓存以提高性能

时间:2015-03-12 16:57:24

标签: javascript jquery performance caching memory

我正在尝试增加移动html 5应用的jquery性能。我阅读了一些关于在全局对象中存储使用过的jquery选择器的指南。该应用程序相当大,我没有预期会有很大的提升,但应用程序的运行速度更慢(如20%)。

我只使用jquery按Id($("#id")或$ _element.find("#id"))查找元素。 Ids是独一无二的,所以我只对寻找第一个元素感兴趣。我设法在cacheHandler对象中全局化所有jquery调用,该对象按id存储所有选择器。缓存经常被清除,每个周期包含大约30个元素。

通过此更改,应用程序运行速度变慢,因此我尝试了一些其他方法来提高性能:

  • cache [id] = $(document.getElementById(" id"))
  • cache [id] = document.getElementById(" id")
  • 使用hashCode存储选择器:cache [id.hashCode()]

我想出了这个想法,这个解决方案很慢,因为内存频繁增加,因为整个dom及其所有子节点都存储在缓存中。

所以我有了新的想法,将元素路径缓存为数组,比如

document.body.children [1] .children [5] .children [0] => [1,5,0]

所以我只需要找到一次该元素,存储数组并查找路径,如果我再次需要该元素。

这并没有改变任何东西,而且每当我需要元素时,所有想法都比调用$("#id")更慢。

如果需要,我可以提供更多信息或片段。

我感谢每个解释,为什么这会减慢我的应用程序。

2 个答案:

答案 0 :(得分:1)

如果它是移动html5应用程序,为什么你使用jQuery选择器?似乎非常多余。

我通常会做同样的事情:

// helpers, since i hate typing document.get ..
function _id(e){ return document.getElementById(e); }    // single id
function _all(e){ return document.querySelectorAll(e); } // single elem
function _get(e){ return document.querySelector(e); }    // multiple elem

// loop helper (for changing or doing things to collection of elements)
function _for(e,f) { var i, len=e.length; for(i=0,l=len;i<l;i++){ f(e[i]); }}


// VARs (global)
var c = _id('c'), // main selector
    box = c.querySelectorAll('.box'), // boxes in 'c'
    elements = box.querySelectorAll('.element'); // elems in 'box'

// Change background-color for all .box using the _for -helper 
_for(elements, function(e){ e.style.backgroundColor = 'red'; }

我只存储元素的主要父元素,以便我可以在需要时查询DOM(限制遍历所需的锁定)。在上面的示例变量中,可以想象.box中的某些内容会多次更改 OR .box是一个慢选择器。

请注意,全局变量会增加内存使用量,因为这些变量可能会干扰垃圾回收。另请注意,在某些浏览器中对象可能会变慢,如果它不会使代码膨胀太多,则应该更明确地存储它(不管怎样都不应存储太多的全局变量......)。

编辑,jsPerf:

<强> http://jsperf.com/global-vs-local-vars-14mar2015

请注意,根据您的选择以及您正在做的事情将产生最大的影响。在jsPerf-example中,一旦开始从全局缓存的选择器中选择后代,即执行box.find('p').css('color','blue')等,本地和全局之间的差异会迅速减小。

答案 1 :(得分:0)

这已经很老了,但我们永远都不知道,有人可以阅读这篇文章。

jQuery基于Sizzle,它更小:https://sizzlejs.com/

您最终只能包含此库。我不建议为此目的维护自己的代码。它已由其他人完成并维护。