Preventing JavaScript Files from Loading Multiple Times

This post is about ensuring that you do not execute a particular JavaScript file more than one time. Let’s start by asking:

What happens if you link to a js file twice in your page?

Here is a contrived example.

Notice that we are including bad-example.js twice. Do modern browsers somehow realize they loaded this file already and skip this? Not yet, as we’ll see!

Imagine bad-example.js had this code in it.

Is jQuery smart enough to know it should only hook this event once per file? Will that div be appended as many times as the file was included when the button named nameIt is clicked?

I’ve created a simple jsFiddle for you to explore this problem before we get to the solution.

Accidentally Included Script Three Times
http://jsfiddle.net/mkennedy/6AHCZ/

In the bottom-right pane, you’ll see the web page running. Enter your name and click the button. You’ll see that you get this output, repeated 3 times per click!

Now, the old saying “I said, doctor it hurts when I do this with my arm. Doctor said, then don’t do that!” comes to mine. Maybe we should just try hard to not include a js file multiple times. In real web apps, it’s not that simple.

I’ve been working on a JavaScript-heavy web application recently. There are a lot of ASP.NET MVC views and layouts as well as a lot of JavaScript files. Currently, a little dir /s reports there are 1,200 razor views and 50 JavaScript files. Many of these are views nested within views which are nested within layouts, and so on. It’s not simple to be certain you’re only including a file once.

So what do you do? Give up and proclaim that JavaScript sucks. It was never meant for building large applications. No, of course not.

The web is awesome and the fix is simple enough.

Let’s look at another example. If we could simply write code like this, we would be in business.

We call fileAlreadyLoaded and bail out if it’s true. You’ll see that by using namespaces (you should do this anyway!) and a simple method which embraces JavaScript’s dynamic nature, we can pull this off easily.

First, for your project, define a global namespace. Let’s assume I’m writing a blog app. So maybe blog is a good base namespace. You see, in JavaScript it’s as simple as this:

This might be good for your main JS file. But you do not want to have just one huge JS file. Breaking things up for maintainability is good. So suppose we have a commets.js file. In there, we’d have:

Notice, it’s not var blog.comments.We’re adding a sub-namespace (object) to the global namespace blog. With namespaces in place, we can add methods to them and get intellisense to boot! Here’s an example of adding a method to the blog.comments namespace.

We can set values such as blog.comments.debugMode = false. And your code becomes much more navigable in Visual Studio with intellisense by leveraging namespaces:

So namespaces are great and all. But the question is…

How do we leverage namespaces for checking whether a file is loading more than once?

Well, if we use one namespace per file and recall that namespaces are just objects we can write that method to check for a double load like this:

We take a namespace and see if it has a firstLoad property. The first time, firstLoad has never been set, so it comes back as undefined. Hence, isFirst is true. We add a little logging to let us know there is trouble if it’s a second load. Then we just return the status.

Anywhere in your js file you need check (only ask once per file!) you can do:

See how we pass the namespace blog.comments which is in the comments.js file?

There you have it. We prevented the execution of a JS file the second, third, etc times it’s included. You even get a diagnostic output to boot.

So for the final part of this post, check out a new jsFiddle which uses the improved script with this testing and with namespaces.

Scripts only once (block multiple)
http://jsfiddle.net/mkennedy/eEBZh/

Now you see, we get just the output we want. Our script was included 3 times and yet it only ran once.

We even got some nice output in the F12 tools!

Hope this is useful or helpful to you!

Cheers,
@mkennedy

5 thoughts on “Preventing JavaScript Files from Loading Multiple Times

    • Hi Bobby,

      Thank you. I did look briefly at require.js. It’s interesting. For this project it’s already underway so changing things too much is probably not an easy option. But I’ll certainly check out your post and consider it for the next one!

      Cheers,
      Michael

  1. Pingback: Dew Drop – October 12, 2012 (#1,421) | Alvin Ashcraft's Morning Dew

  2. Hi Michael,

    I read your post – and I stopped at the point where you’re saying “Is jQuery smart enough…”

    The thing is, the JS file might be included multiple times on purpose by the programmer – I know it’s bad programming practice but my point is that jQuery is not responsible to fix bad code – and I don’t think that we, as programmers should expect it to do so.

    • Hi,

      Sorry you stopped reading. If you hadn’t, the next sentence would have taken you to a jsFiddle which shows *obviously* that jQuery does not do this.

      http://jsfiddle.net/mkennedy/6AHCZ/

      I can conceive of a alternate world where jQuery would check these sorts of things for you. I think it’s a fair question. But if you read on, you would have seen that I do not have this incorrect. Further, I would guess that it’s greater than 999/1000 times including JS files twice is not on purpose but rather is a mistake with unintended consequences. For the exceedingly rare case when you need to run a file multiple times (ever?), don’t use this technique. :)

      Cheers,
      Michael

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s