Requirer

Get things when you need them by Tobias Krogh

On larger platforms like XING there are many JavaScript modules and helpers which are bundled into a single file for performance reasons. Since you do not necessarily need most of them on every page it would be great to be able to only load such files when they are actually required. The advantage for our users is that they can work faster with the page, less data is loaded initially. We investigated this for quite some time and came up with a mechanism we call Requirer. Normally you load JavaScript files by placing a script tag into the head.

Current implementation

As you can imagine, we use a lot of JavaScript every day so we need it to be easily accessible from anywhere. So let’s have a look at an example:

<head>
  <!-- bundled file with MyClass and many other classes -->
  <script src="path_to_all_classes.js"></script>
</head>
 
<body>
  <div id="expand-me">Some hidden content</div>
  <script>
    new contentExpander("expand-me");
  </script>
</body>

So the code required for contentExpander has already been loaded when loading the whole page. But the problem is that we probably only need 1 kb out of 70 kb (for example). On this page the other code pieces are not used at all and are thus redundant at the moment.

Doing the same with our “Requirer” would look a lot nicer

Here we can load modules on demand, i.e. exactly when you want to work with them. After a file has been requested, it remains in the cache and therefore every other occurrence can make use of that. And don’t forget that there is no need to know where the file is located or whether it is loaded at all!!! We can request it in every file or inline script whenever we want it.

<head>
  <script src="requirer.js"></script>
</head>
 
<body>
  <div id="expand-me">Some hidden content</div>
  <script>
    // we use xing.require as a shortcut
    // constructWith calls "new contentExpander()"
    xing.require("contentExpander").constructWith("expand-me");
  </script>
</body>

Now we have a clean head while still being able to create the contentExpander in a short and simple way. What’s even better is the fact there is no need to know the path or even the existence of this module.

This is realized by returning an object promise on which “constructWith” and “afterLoad” can be called to pass in either arguments for a class instance or setting a callback when the load has finished. The methods are executed once the request has finished loading.

In the future we plan to extend this mechanism to load multiple modules at once.

Conclusion

Nowadays, reducing page size to gain performance is not always the most important issue. But in a world where JavaScript is being increasingly used to deliver an experience rather than a static homepage, we should keep an eye on site performance. It is not unusual for people to visit out page using a large mobile device. Here we can and should deliver a fast but nevertheless astonishing experience. The Requirer can help us to achieve that aim.

About the Author

Tobias KroghTobias Krogh works for XING as an enthusiastic Frontend Engineer. JavaScript is his language besides using semantic markup. XING Profile »

Leave a Reply