简体   繁体   中英

Global JQuery Selector caching to increase performance

I am trying to increase the jquery performance of my mobile html 5 app. I read some guides about storing used jquery selectors in global objects. The app is pretty big and I didn't expected a big perfomrance boost, but the app was running even slower (like 20%).

I only use jquery to find elements by Id ( $("#id") or $_element.find("#id")). Ids are unique, so I am only interested in finding the first element. I managed to globalize all jquery calls in a cacheHandler object, which stores all selectors by id. The cache is cleared frequently and contains around 30 elements per cycle.

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")
  • store selectors with 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.

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]

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.

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? 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). In the example variables above one could imagine that something in the .box would change several times OR that .box is a slow selector.

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:

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.

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/

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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