3

I am working on an intranet website where there is a lot of interaction with the main page. The site uses jQuery extensively. So I thought about caching the jQuery selections the first time they are requested and pull them from the cache for each subsequent request. (I also have built in an override if I want to force a re-selection).

Here is the basic snippet of code I am wondering about:

( function(window, $, undefined) {
  var mp = {};
  mp.cache = [];
  mp.get = function ( selector, force) {
    return ( !force || !mp.cache[ selector ] )  /*separating for readability */
           ? mp.cache[ selector ] = $( selector ) 
           : mp.cache[ selector ];
  }

  /* more functions and code */

  window.mp = mp;
  window.$$ = mp.get;

})(window, jQuery);

It would be used just like a normal jQuery selection but checks to see if that selector already exists in the cache array and, if it does, just returns the results from there.

UPDATED EXAMPLE

$('#mainmenu').on('click','.menuitem', highlightSelectedMenuItem );

function highlightSelectedMenuItem () {
  var menuitems = $$('.menuitem'); //selected first time, from cache every other time
  menuitems.find('.current').removeClass('current');
  $(this).addClass('current');
}    

There are about 20 - 30 different selections in the code. So each would be cached on first call. This code will only be run on desktop clients (no phones/tablets).

Good idea? Any issues this might cause? Is there a good way to test if this helps/hurts performance? Any pros/cons you can come up with would be appreciated.

Let me know if more information is required.
Here is a fiddle to "fiddle" with.

Thanks!

Gary Storey
  • 1,779
  • 2
  • 14
  • 19
  • Possible duplicate : http://stackoverflow.com/questions/10055165/performance-of-jquery-selectors-vs-local-variables – Liam Aug 28 '14 at 20:04
  • Not a duplicate. I am not talking about caching the selector in the same function call as per the question you mention. I specifically said that.... – Gary Storey Aug 28 '14 at 20:09

3 Answers3

3

Bottom line: Probably a bad idea.

You're introducing complexity that is likely unnecessary and is likely just going to eat up memory.

If you're trying to speed up selections that are repeated, then store the selection in a variable. When it's no longer needed, the garbage collector will remove it. For 99% of applications out there, that's as much caching as you need.

A big problem with your example is that the items you've selected will stick around indefinitely. Think about the people who may work on this code later. Everyone may just start using $$('....') because they see it in a few spots and it does the same thing as $('....'). Suddenly you're storing thousands of DOM elements in memory for no reason at all.

Beyond that, if the DOM changes and you don't know about it changing, the code that you have in cache is useless.. but unless you're forcing it to reload then you'll end up continuing to get that cached code. Which of course introduces bugs. In order to prevent that from happening, you'd have to force reload the cache constantly, which pretty much negates the usefulness of it.

You're going to be better off just following good, solid programming patterns that are already out there.. rather than programming up a caching mechanism that is going to be a bug magnet.

Stephen
  • 5,362
  • 1
  • 22
  • 33
1

I made your question into a jsperf, and I found that un-cached jQuery appears to run faster.

http://jsperf.com/jquery-cache-array-test

because of this I would recommend just using pure jQuery.

howderek
  • 2,224
  • 14
  • 23
  • Thanks for setting this up! So each time it runs the test does jsperf "reset" the environment? Or does it continue with the same for each execution? I am not familiar with how it works. – Gary Storey Aug 28 '14 at 20:21
  • The environment does not reset, your code is caching as expected. – howderek Aug 28 '14 at 20:25
0

I think it's a bad idea. If you need to use a selection in several places the save the selection to a variable. var mySelection = $(#myId).

it will be garbage collected when its no longer needed.

Steve Farwell
  • 520
  • 3
  • 5
  • That is essentially what this technique does. It just puts the results into an array so that there isn't pollution of the global namespace. – Gary Storey Aug 29 '14 at 15:30