 Hi I'm Adam Sontek. I'm a developer at Boku, and I'm the developer Developer Relations Lead of the jQuery Foundation, and I'm here today to talk to you about a subject that's near and dear to my heart The caching of jQuery and DOM selections in two variables I'm too often. I see people just making insane jQuery selections and then repeating them over and over again or Sort of using the DOM as like a database that they look out create these complex selector strings pulling things together dynamically and It's expensive and it's ugly and it's hard to talk about so Today I want to talk about why caching selectors is Useful and can help make you a better programmer So let's take a look at a typical example. Let's say we had an image tag and There's a chipmunk in it now the typical Okay, I want to go change the source of this to be a different chipmunk jQuery approaches. All right, go grab it and Now change it to other chipmunk and then I later on it's someone else in the app Oh, I've got a add a border to it. So it's been activated somehow. So let's Activate it Magic hey, cool What's wrong with this? Why am I going and querying the DOM again? Exactly that's what's wrong with that. I'm going and querying the DOM again if I was using traditional native DOM methods like Document get element by D and I wanted to go get the foo element I do their foo equals document, get element, and if I wanted to do more stuff to it I obviously would be using a variable because because document get element by ID is so much typing that I can barely stand to write it twice So we got another chipmunk.jpeg and we're setting it with the native DOM And then if I wanted to set the class name, I would do it again Anyhow now this obviously still applies with more complex selections whether with jQuery or with diet native DOM methods so if we were looking at like a Nav kind of element here, and we had a bunch of animals in that and I wanted to go get the active one maybe I would go do Nav and then if I wanted to do something I Would and then let's say I wanted to go activate the next one. I would maybe keep on chaining So I get this nice long jQuery chain wahoo so What I'm here to encourage you to do is Save almost all your collections into variables or in onto objects or somewhere where they're more meaningful so What I'm proposing is their Active items and then when I want to go work with this afterwards. I'm gonna go do active items Now some people are actually surprised by the fact that this works But really jQuery is no different than any other function call It returns what it returns and you can then save that into a variable. So in the same way that if I have a String and I call a method on it and I have two variables and I have two variables and it keeps on working So it works the same with jQuery another mistake that I see people make when they're Getting used to doing this is they kind of think that jQuery is like a blanket that you always need to wrap things in in order to be able to call more jQuery methods So they'll have Rata Saved it a reference to a collection But then if they want to go do something they'll read jQuery it because you know better safe than sorry as it turns out That's not really true. So if you do this Is absolutely redundant You may also notice that all these variables that I'm creating where I save references to jQuery objects Are preceded with a dollar sign? This is just a convention that a lot of people follow in order to denote that the variable refers to a jQuery collection and you can expect all of the Methods that you're used to on a jQuery collection add class remove class siblings You animate the whole kit and caboodle Some people really like this and other people really hate this It's called Referring to it as Hungarian notation, which is the practice of naming your variables with a prefix that denotes the type This is it works really well for this presentation It works well for examples, but you can feel free to use it or not. It doesn't really matter So a lot of people say well my application seems totally fine and it seems totally fast Why should I bother start caching these selectors as long as I'm not As long as I'm doing fast selections, and I'm not doing making use of proprietary jQuery selectors like first it thing oh Or a check box Where I'm using Any sort of mod selectors that are supported by query selector all then I should be fine everything's fast. It's no big deal and Others if you may have heard that Selectors are like really really really slow and the main reason your app is having any Sluggishness is because you must have slow jQuery selector. So here's the fastest jQuery selector to use that era is sort of ending and As long as you're not repeatedly doing selections over and over again selections can tend to be pretty fast however, a lot of people fall into this trap of Repeatedly making bad selections. So they'll go into like a window scroll Handler which is fired repeatedly over and over again as the window scrolls and then they'll do something like you know Select the first thing and do some kind of crazy animation on it. Now. This is the kind of thing that makes sad faces and Crying kittens the whole works So this is bad, let's say that it's bad But if you're not if you're not doing that, you know, if you're being a good Programmer or a disciplined jQueryist and you're saving all of the Li's outside of this thing Not so bad Why is it important beyond just this performance increase that? I start saving my collections. I Think that it's because Constantly querying the Dom to the sign that your application isn't really in charge. You're sort of just grabbing things and passing them around and Coming up with awesome selectors like Thing concatenated with my variable plus and then a space and then other thing and then this It's a hole and then I've got another very and your eye how your whole app starts to look like this and you can't talk about it Beginning to think of these element collections as sort of a low-level building block of your app rather than the entire thing it's an important step in Not Slathering on bits of jQuery and hoping it gets by but beginning to develop applications So what am I really talking about? Let's take a look at a sort of Sample and sort of very real application Which is this Display of animals forest animals in the winter time in the summer time It works pretty nicely. We got a cycle going on and there's it shows, you know the deer In the winter in the summer and the rabbit in the winter in the summer and it's really cute and Snazzy, so how am I doing this? Oh, I'm using lots of selectors check that out So first when the application kicks off I go and make a cycle plug-in on each of these animal slide shows and When one of these gets clicked I go read stuff out of the dom using an href I go find the Corresponding ID and find where it is amongst its siblings and then tell the cycle plug-in to select the one that I just clicked on and Then sort of along the way here in the document ready function I'm saying oh by the way I should initialize the first one is active and then I also have an event listener that says anytime the first slide show changes I'm gonna go and And update this active class on the menu so that the current one is highlighted Notice here. We have a lot of concatenation together of selectors So Every everything in the HTML here has like a lot of IDs and we're using hrefs and we're parsing the hash out And we're doing this kind of fun pars You know all kinds of hair brain stuff so that we can drive the interaction here using basically nothing but selectors So what what's problematic about this is that there's no Structured and if you and I were working on this important application together It's really hard to talk about and it's all about these collections that you're inside of one Handler go query the whole dom go find the cycle the element that we know of the cycle plug-in and and Call a method of the plug-in that we know is initialized. It's it's completely ad hoc. It feels to me what if instead of Just kind of having these random collections and just querying the dom all the time we Got what we needed to work with up front and then worked with it So let's take a look at a slightly different implementation of this same thing here So we've made two major refactors here The first is that we're not using anchors anymore as buttons because they're not really we don't want them to be links Again, and we've cut down on the number of IDs. We have all over the place So instead we have data attributes that we're using So that in our application we can grab the pieces of information out of the dom and then work with them later but only grab them once up front and again, we're using a similar approach in the refactored code so the first thing we do is we save and name some collections that we can then Use and talk about later. So we save a reference to the animal slideshow in the summer section and the winter section and then we Create another collection of the navigation items Way up front and then we have the summer and we have the winter and we have some animals Then we initialize our cycle and Instead of just making another ad hoc selection we say I want to add cycle functionality to the summer and the winter sections again Since we're also in the beginning of the code We're going to add this active class to the first animal, but notice that it's not just going and grabbing Nav li first and adding An active class to it. It's going to this already existing animals collection and grabbing the first one Which when we're talking about our code together again is a lot easier for us both to grog our Click handler is refactored and Only slightly to use the data attribute jQuery when you have data Attributes in the HTML reads them in so you can read them with the jQuery data API and Notice how all these method calls are on pre existing selections. So when one of the animals is clicked We execute this handler inside of the summer collection go and find the index of the animal that you clicked in the same thing for the winter and Again with our cycle handler instead of going back to the DOM we are going back to Collections we already have in memory and we're filtering them or Looking inside of them for more elements. It's not just I'm grabbing everything as I need it and Okay It kind of works We actually have something that's beginning to resemble an application because we've started to separate the beginning from the middle What's interesting also in terms of selector performance one of the things you always hear is always descend from an ID Which is it's just it's a good idea But the point is there's a difference between descending from an ID and doing and actually going and running queries a query selector all under the hood versus actually always referring back to your original collection and Looking for those and then looking for the divs inside of it It's it's all about That famous axiom keeping your code dry and don't Repeat yourself It's not just about writing code that is not duplicative of other code It's about not repeating actions that don't need to be repeated so if The beginning of our application is the time to grab the things in the down we're going to work with and then the middle of the application is the time to facilitate the relationships in between them using jQuery so what's interesting about this approach is that as you start to Organize this code more it starts to begin to resemble the client-side MVC approach that's becoming popular To say the least things like backbone and angular and ember where jQuery is not necessarily The lead dog. It's more like a swiss army knife that Everyone uses because it does a million things, but you don't put together the entire house with it We'll talk about some of those things in a future screencast how to start making this less of a Situation of let's go find out things about the dumb and sort of pick our way through it But rather to use the dumb to represent The application, but that's a story for another day in the meanwhile What do I want you to take away from this? It's that cashing your selectors is easy and it's awesome you have an easy way to increase the performance of your application and whether you're using a ton of selectors already or You have started to implement this approach where you feel like you have to but You're not doing it all the time because No one's forcing you to I would say Don't create twice what you only need to create once There will be situations where you might have to write crazy crazy selectors like what if you're writing some kind of browser extension and The only way to get the data to bootstrap the beginning of the application is to write like something like you know Find all the TDs and then grab their easy checkboxes inside of them You know something crazy like that Or worse You know, what's added? You know a positional selector in there too Even though that's again queries like draw again a selector like this Actually not as bad as it once was but Even if it isn't as bad as it once was Save it once and for the rest of your application. Just talk about the boxes that you're using so I hope that this has given you some perspective on How to think about saving references to your collections and more importantly emphasize that it's good For Your app and it's good for your Relationships with your colleagues and it's good for your development as a front-end engineer Until next time Thanks