email@encode8.com
JavaScriptResources

How to Conditionally Load JavaScript files

Minimizing asset loading time and increasing performance of a website is a web-developer’s first priority. These days most websites depend heavily on several JavaSript and CSS files including third-party ones. You can add all of them in your head tag (or at the end of body). Or you can lazy-load them later depending on certain conditions.

Why conditionally load resources

Loading all JavaScript files at once can drop site performance significantly. Needless to say, if your site is slow, users will stay long enough to finish loading. There is yet another reason why you may want to load JavaScript at a later stage: You may not need all the javascript for every user. Depending on the browser, location and device among many other factors, there can be separate file for each case. Performing the tests and loading libraries depending on the result is the right thing to do in such cases.

Why not use deferred

JavaScript used to provide a deferred attribute to load files at a later stage. But the method has been deprecated and replaced by Promise class. Besides, this method did not let you load files depending on a certain condition — it just loaded them later.

How to load libraries based on conditions

There are several things you can do to load JavaScript (and CSS stylesheets for that matter) depending on certain conditions. Here I am going to discuss two methods.

1. Using vanilla JavaScript

You can perform a certain check with vanilla JS. And then, depending on the result, you can create a script tag (inside head may be) and set the src attribute to the url of the source file.

For example, let us say you want to load separate resources for desktop users and for mobile users. You can use this:

var script = document.createElement("script");
    script.type = "text/javascript";

if (window.matchMedia("(max-width: 568px)").matches) {
    script.src = "//path/to/mobile-users.js";
} else {
    script.src = "//path/to/desktop-users.js";
}

document.body.appendChild(script);

The above code creates a script tag and performs a test with window.matchMedia. If the results show that the user is on a mobile device (max-width is 568px, e.g.), then set the source of the script tag to the javascript file intended for mobile-users. Otherwise, set it to desktop-users.js. Finally, it appends the script tag to the end of body. You can use similar logic for CSS stylesheets (create a tag, set rel to stylesheet, etc.)

2. Using jQuery

However outdated you may tag jQuery, it is still widely used. Using jQuery, you can achieve the same conditional resource loading, with less amount of code. jQuery provides a getScript method to load JavaScript files and execute them. For instance, you may have:

if (window.matchMedia("(max-width: 568px)").matches) {
   $.getScript("//path/to/mobile-users.js");
} else { 
   $.getScript("//path/to/desktop-users.js");
}

This is a lot less amount of code but it is useless if you want to conditionally load CSS stylesheets.

3. Carl.js

Carl.js, short for Conditional Asset Resource Loader, is a tiny yet useful JavaScript library that lets you load CSS, JavaScript and even HTML files, depending on test results. Carl.js can be used by simply writing a resources.json file. The syntax is dead simple — for each condition, write a test and an array of resources to load if the test passes. It is something like this:

{
   "form.login-form":
     [ 
       "/path/to/login-form-styles.css",
       "/path/to/login-logic.js"
     ]
}

The above code will load a JavaScript and a CSS file only on form tags which has a class login-form.  Carl.js is very useful on large projects where you want to organize individual resources. Indirectly, it forces you to break web-pages into small and reusable components.

Conclusion

Resource-heavy web-pages need more care when it comes to delivering JavaScript libraries and CSS stylesheets. In order to ensure optimal page-speed without sacrificing user-experience, conditional resource delivery is more beneficial than monolithic html structure. I personally prefer using Carl.js over the other two methods I described above. This is mostly because I forces me to write reusable components. Plus, it is more convenient to manage the resources from one single file.