简体   繁体   English

全局JQuery Selector缓存可提高性能

[英]Global JQuery Selector caching to increase performance

I am trying to increase the jquery performance of my mobile html 5 app. 我试图提高我的移动html 5应用程序的jquery性能。 I read some guides about storing used jquery selectors in global objects. 我阅读了一些有关在全局对象中存储使用过的jquery选择器的指南。 The app is pretty big and I didn't expected a big perfomrance boost, but the app was running even slower (like 20%). 该应用程序相当大,我没想到性能会大大提高,但是该应用程序的运行速度甚至更低(例如20%)。

I only use jquery to find elements by Id ( $("#id") or $_element.find("#id")). 我只使用jquery通过ID($(“#id”)或$ _element.find(“#id”))查找元素。 Ids are unique, so I am only interested in finding the first element. ID是唯一的,因此我只对找到第一个元素感兴趣。 I managed to globalize all jquery calls in a cacheHandler object, which stores all selectors by id. 我设法全球化了cacheHandler对象中的所有jquery调用,该对象按ID存储所有选择器。 The cache is cleared frequently and contains around 30 elements per cycle. 缓存会经常清除,每个周期包含大约30个元素。

With this changes the app ran slower, so I tried some more things to increase performance: 进行此更改后,应用程序的运行速度变慢了,因此我尝试了一些其他事情来提高性能:

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

I came up with the idea, that this solution is slow, because the memory is increased frequently, because the whole dom with all its children is stored in the cache. 我想到这个解决方案很慢,因为内存经常增加,因为整个dom及其所有子项都存储在缓存中。

So I had the new Idea, to cache the element path as array, like 所以我有了新的想法,将元素路径缓存为数组,例如

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

So I just have to find the element once, store the array and look up the path, if I need the element again. 因此,如果我再次需要该元素,则只需查找一次元素,存储数组并查找路径。

This doesn't change anything, and all ideas were even slower than calling $("#id"), whenever I need the element. 这并没有改变任何东西,并且每当我需要该元素时,所有想法甚至都比调用$(“#id”)还要慢。

If needed I can provide more informations or snippets. 如果需要,我可以提供更多信息或摘要。

I am thankfull for each explanation, why this is slowing down my app. 感谢您的每一个解释,为什么这会使我的应用程序变慢。

If it's a mobile html5 app why are you using jQuery for selectors? 如果它是移动html5应用程序,为什么要使用jQuery作为选择器? Seems very redundant. 似乎非常多余。

I usually do somthing along the lines of this: 我通常按​​照以下方式进行操作:

// 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'; }

I only store main parents of elements so that i can then query down the DOM if needed (limiting the lockup needed for traversing). 我仅存储元素的主要父元素,以便随后可以根据需要向下查询DOM(限制遍历所需的锁定)。 In the example variables above one could imagine that something in the .box would change several times OR that .box is a slow selector. 在上面的示例变量中,可以想象.box中的.box将更改数次, 或者 .box是一个缓慢的选择器。

Do note that global variables increase memory usage though since those variables can interfer with garbage collection. 请注意,全局变量会增加内存使用量,因为这些变量会干扰垃圾回收。 Also note that objects can be slower in some browsers and if it doesn't bloat your code to much you should instead store it more plainly (you shouldn't store too many global variables anyway so....). 还要注意,对象在某些浏览器中可能会变慢,并且如果它不会使您的代码膨胀得太多,您应该改为更简单地存储它(无论如何,您不应该存储太多的全局变量。。。)。

Edit, jsPerf: 编辑jsPerf:

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

Do note however that depending on what you're selection and exactly what you're doing will have the greatest impact. 但是请注意,根据您的选择和所从事的工作,所产生的影响最大。 In the jsPerf-example the difference between local and global quickly diminishes as soon as one starts selecting descendants from the globally cached selectors ie doing box.find('p').css('color','blue') etc. 在jsPerf示例中,本地人和全局人之间的差异一开始就从全局缓存的选择器中选择后代,然后迅速减小,即执行box.find('p').css('color','blue')等。

This is quite old but we never know, someone can read this post. 这已经很老了,但我们永远不知道,有人可以阅读这篇文章。

jQuery is based on Sizzle which is way smaller: https://sizzlejs.com/ jQuery基于较小的Sizzle: https//sizzlejs.com/

You can eventually include only this library. 您最终只能包含此库。 I would not recommend to maintain your own piece of code for this purpose. 我不建议为此目的维护您自己的代码。 It is already done and maintained by someone else. 它已经由其他人完成和维护。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM