Don't Initialize All the Things in jQuery.ready()

One of the first impressions a user gets is loading your web application for the first time. Users don’t have a high tolerance when it comes to page speed. They want to see something almost immediately and then be able to start interacting with your web site shortly after.

If your website utilizes JavaScript and jQuery, which many web sites do, it is very tempting to pre-initialize all of your logic (plugins, widgets, modules, event handlers, etc) in order for them to respond as fast as possible. Unfortunately, initializing ALL THE THINGS during page load works against the user’s goal of loading quickly. Instead of initializing everything when the page is ready you can instead wait to initialize portions of your application until they are needed.

The following examples will show two ways of initializing a date picker. The first way will “Initialize All the Things” and the other example will use the “Just-In-Time Initialize” principle.

Example Markup

In order to convey the idea I’m trying to explain it is probably easiest to show a code sample and then talk about what is happening. We will be using the following HTML for the markup that our code examples will be using.

I am using Twitter Bootstrap to made the UI look more presentable and that is why you are seeing some extra classes attached to the above markup.

The markup shows a simple form with various input elements. In the form we will have multiple date fields that we will want to initialize using the jQuery UI datepicker widget.

Initialize All the Things

The following jQuery code looks familiar to many snippets that you’ll might find across the internet, in tutorials, and possibly in your web applications.

I am using the small moment.js library to help with data manipulation. It is a handy date library that I think you'll find very compelling and rich with features.

Let’s unravel what the code is doing…

  1. We wait until the document is ready before running the rest of our code.
  2. Once the DOM is ready, then select all the input elements on the page with the date class.
  3. jQuery will implicitly iterate over it's internal collection of elements and initialize each one with the datapicker jQuery UI widget.

Pros of this Technique

Cons of this Technique

Just-In-Time Initialize

The following code snippet looks considerably different from the previous example, but the end result is the same and the Pros and Cons are quite different. See if you can spot out the differences.

You can view, run, and edit the above code sample from JsFiddle or you can interact with the embedded version below.

I am using the toastr library to show messages indicating when the elements were initialized. This library was created by Hans Fjällemark and John Papa.

As we did in the previous example let’s outline what is happening in the code and then we will examine the Pros and Cons of this technique.

  1. We immediately set up an event handler to wait for User Input before initializing the datepicker. This allows the code to run immediately after jQuery has been executed on the page before the DOM is even ready. We don't need the DOM to be ready because we are delegating our event to the document context.
  2. We aren't initializing all the input.date element, but are only listening to the focus event. This event will propagate (a.k.a. bubble) up the DOM tree until it gets to the document at which point jQuery will determine if the item focused on matches any of the metadata it has stored. This metadata match is surprisingly fast because it is only matching this "crazy" selector against the one DOM element that was focused on and not the whole DOM tree.
  3. Our advanced selector is looking for input.date element that doesn't have the hasDatepicker class. If this is a match then that one DOM element will be initialized. After that point, if the element is focused on later the selector will no longer be a match because jQuery added the hasDatepicker class during the it's widget creation.

Pros of this Technique

Cons of this Technique

Conclusion

You want to limit initializing all the things all the time. It can be helpful if you start to think about delaying initialization until the point when you need it or possibly right before. By doing so you can utilize the time right after jQuery is executed and not wait for DOM ready then you are able to use that precious time during page load. In addition you can have a crazy weird jQuery selector that still is fast. In our last code example above had a complicated selector, but it was very fast because it is only being tested against the one element that was focused on and not the whole DOM tree.

Much of this material was gleaned from an awesome series Doug Neiner has given at the past several jQuery Conferences entitled "Contextual jQuery" (video & slides). If you haven't already seen his talks or slides I highly encourage you to go through them.

If you enjoyed this post, please consider sharing it with others via the following Twitter or Reddit buttons. Also, feel free to checkout my egghead.io profile page for addition free and subscription lessons, collections, and courses. As always, you can reach out to me on Twitter at @elijahmanor. Thanks and have a blessed day!

Reddit