feature-image

Introduction

Have you ever felt like sitting on your hands while waiting for your project to build so that you can test your code? Have you ever found yourself on a website that seems to be stuck in a staring contest with a blank screen, playing an eternal game of loading animation, leaving you wondering when it will finally reveal its webpage secrets? If yes, I have definitely experienced that too! It’s like waiting for a mystery to unfold, and you’re stuck in the suspense of the loading dots. 😅

Understanding the Problem:

The central issue stems from a common practice—loading all resources upfront. This approach, while seemingly efficient, often leads to extended loading times and delays in rendering web pages. A large-scale project will typically have a number of features, with each one of them as unique as possible which in turn require libraries from different spectrums to meet the requirements. The irony here is a user(s) of certain personas will be focusing on certain/limited features in that application. Loading a gazillion libraries upfront may affect the performance when the user is interacting with the application. Most of us would have been bumped by this situation and sought to handle it the best way possible! One approach that we’re relying on is Dynamic loading.

Dynamic Loading:

A way to solve the above problem is dynamically loading the libraries.Different parts of a web application may require different libraries. Dynamic loading allows developers to conditionally load libraries based on the features a user interacts with, optimizing resource usage.

To harness the capabilities of dynamic loading, developers can leverage RequireJS.

The Role of RequireJS:

RequireJS stands as a versatile JavaScript file and module loader, serving as a pivotal tool in optimizing web application efficiency. As articulated by the official documentation, RequireJS empowers developers to dynamically load JavaScript files and modules on demand. This strategic approach enhances application performance by selectively fetching and incorporating only the essential code precisely when it is needed.

Embark on your RequireJS journey:

Download RequireJS from the official site, harness the power of CDN, or seamlessly install from the npm repository.

Dynamic Loading of Libraries:

Exploring the capabilities of RequireJS, let’s delve into the structure of a simple project for a comprehensive demonstration.

blog-img

To kickstart the journey, incorporate the downloaded require.js file into our project by leveraging the script tag.

1
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.js"></script>

In this project, we aim to achieve dynamic loading of three libraries with the assistance of RequireJS. To keep things straightforward, I’ve designed a basic function within each library, showcasing the seamless integration facilitated by RequireJS.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
/* greet.js */
function greetHim(name) {
  alert(`Yo, Marvelous Mind!(${name})`)
}

/* order.js */ 
function placeOrder(item) {
  alert(`[${item}] - Order successful!`)
}

/* deliver */
function deliverProducts() {
  alert(`Here are your items!      
               - Friendly Neighbourhood SpiderMan`)
}

Now, let’s delve into the configuration process. At this stage, we establish an agreement with RequireJS, providing it with the locations of our libraries and assigning them memorable names. This way, when we request RequireJS to load a library by specifying its name, it seamlessly fulfils that request.

1
2
3
4
5
6
7
require.config({
         paths: {
             greetFile: 'libraries/lib1',
             orderFile: 'libraries/lib2',
             deliveryFile: 'libraries/lib3'
         }
     })

In the provided code snippet, we furnish an object to the require.config() method. The paths property within this object serves as a standard field where we establish associations between library locations (e.g., libraries/lib1) and custom names (e.g., greetFile). This process is akin to assigning unique shortcut keys to each library location, simplifying subsequent requests to RequireJS for loading specific libraries.

blog-img

On our website, we feature three buttons, each geared to dynamically load its designated library and trigger the associated function upon being clicked. Take the Greet button, for example. When clicked, it initiates the following code, responsible for loading the greet.js file—notice the use of the greetFile shortcut name established in the configuration object to denote the library location—and subsequently invoking its greetHim() function with the argument name.

1
2
3
4
5
6
function greetUser() {
         require(["greetFile/greet"], () => {
             greetHim("Tony");
         })
         greetHim("stark") /* this is not accessible outside the callback function*/
     }

In the function greetUser(), we employ RequireJS to load the greet library by specifying its name within an array. Upon successful loading, the library’s functions become accessible within the callback function. This approach ensures that each library maintains its isolated scope, mitigating potential naming conflicts in the global namespace. By managing dependencies with RequireJS, libraries operate independently, enhancing modularity in the codebase.

Now, let’s witness the outcome in action. Upon clicking the Greet button, you’ll observe in the Elements tab that the greet.js file dynamically loads within the script tag. Subsequently, the greetHim() function is invoked with a specified name, triggering an alert that gracefully appears on the screen.

blog-img

Conclusion

The dynamic loading of libraries using RequireJS emerges as a powerful strategy, enhancing the efficiency and maintainability of our projects. By selectively loading only the necessary modules when required, we optimize resource utilization and foster a modular, organized codebase. The simplicity and flexibility provided by RequireJS empower developers to create more scalable and responsive web applications. So, the next time you contemplate optimizing your project’s performance, consider embracing the dynamic prowess of RequireJS.