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

21 comments

    • 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

  • 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

  • Hi Michael,
    This is a interesting and easy to understand. Thanks.
    While this is definitely useful, I have a slightly different duplicate files issue. Using jQuery dialogs, ever time I open the same UI the javascript files are loaded again. The file act odd also, and when adding break points the debugger never stops. I’m using IE. I should probably implement your solution anyway. Thanks

  • Very nice and complete article.
    If you however want a more simple solution, you can use the following compact script:

    *FILE: my_demo_plugin.js

    if ( window.namespace_my_demo_plugin === undefined) {
    window.namespace_my_demo_plugin = true; // Run one time only!

    // ... Put your code here, which will run only one time!
    

    }

    The ‘window’ object variable can be used to make sure that variables you define are static and available between scripts.

  • Hi Michael, this is a very nice and complete article.
    If you however want a more simple solution, you can use the following compact script:

    *FILE: my_demo_plugin.js

    if ( window.runonce_my_demo_plugin === undefined) {
    window.runonce_my_demo_plugin = true;

    // ... Put your code here, which will run only one time!
    

    }

    The ‘window’ object variable can be used to make sure that variables you define are static and available between scripts.

  • Hi MICHAEL,

    In my website, JQuery is loaded on the head section – http://www.example.com/wp-includes/js/jquery/jquery.js. (I also have the “preload” resource hit for my website’s jquery.js file, on the head section).

    The Google Ads also requests JQuery from – https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js. Sometimes, the Google Ads request it twice. How can I make this as a single request? Also, I want the browser to process the JQuery file once (since mobile phones become unresponsive for few milliseconds when processing a large set of JS files).

    Thanks in advance.

  • Hi Michael,
    Should we replace the namesp with the namespace name? As i am beginner, i did not understand your jsfiddle example.could you please explain where to put the codes?

  • Hi Michael, Can you please explain how the browsers can skip that already loaded js files. What are that modern browsers it does.

    • Hi! They don’t skip it, exactly. But the technique in the javascript page stashes a loaded value in global namespace and just bails out right at the top if it finds that there (only reason it would be there is it loaded already).

Submit a comment