banner-dynamic-import.jpg

What are Dynamic Imports and how to use them?

Nov 4th, 2020 | Tushar Mane

Dynamic imports or Code Splitting is the practice of breaking up your JavaScript modules into smaller bundles and loading them dynamically at runtime to improve and increase the performance of your website dramatically.

Before we go into Dynamic imports lets review why are we talking about this topic. In one word the reason is “Performance!”

To improve performance of the modern day websites which commonly rely on a number of javascript modules, frameworks and 3rd party libraries developers often resort to concatenating, combining and minifying libraries into as few files as possible. While this definitely improved load times of the sites, it caused some other concerns. A vast majority of the pages of most websites load the same large JS bundle even if majority of the code is not even needed for most pages. This often leads to longer processing time by the browser, high memory usage and, the network lag is never completely solved for slower connections due to larger sizes of the bundles.

With the combination of HTTP/2 protocol (multiplexing support) , and browser caching, the ideal way to improve performance of your website for all devices is by splitting your bundles into smaller chunks and dynamically loading the necessary chunks if/when needed.

To solve the performance problems of today’s websites we need to explore hybrid solutions. We need to reduce the number of files being downloaded by combining commonly used JavaScript modules or common dependencies into a common bundle and, split the not commonly used JavaScript modules into separate bundles which can be loaded on demand only where applicable.



Static Import

Static imports is the standard way to import a file at the top of your js module using standard import syntax. With static import all modules are imported at the top of your JS file and, generally the build process will concatenate the JS files into a single bundle which gets loaded on all pages.



Dynamic Import

With dynamic imports, the import statements are written in inline function calls within modules.

As shown in the video example above, with Dynamic import approach, the vendor file is dynamically loaded by the HTML page if a carousel is detected on the page. Pages which do not have a carousel do not incur the overhead of loading the vendor library required to support the carousel thus reducing the overall page load weight and increasing performance.



When should you use it ?

  • Conditional Importing – If a large module or vendor library is needed in specific pages or areas of the site, you can conditionally import using this approach.The static import is still preferable for loading initial dependencies and can benefit greatly from static analysis tools and tree shaking.
  • When the module you are importing does not exist at load time, you can wrap the module dependent code inside the .then() block and handle exceptions in .catch() block.
  • Modularizing the code – Modules can be called based on their need same as fetching data from the server.


Lets take look at the implementation

Syntax

import('</url-to-module.js?>').then(
    (module) =?> {
        //  Do something with the module
    }
).catch(
    (error) =?> {
        // handle the case where module didn't load or something went wrong
    }
);
  • <url-to-module.js?> : URL/path for a module that you like to import dynamically.
  • then() : To handle logic after inserting module code.
  • catch() : For error handling like if module not found or any exception in then ( ) block.

Example

In the below example of Static Import, we are using a 3rd party tiny slider library to render a carousel.

import { tns } from 'tiny-slider/src/tiny-slider'; // Standard Import
 
const selectors = {
    tnsId: "#tns-items",
    tnsCntrlsId: "#tns-controls"
};
    
let tnsContainer = document.getElementById(selectors.tnsId);
 
if(tnsContainer) {
    tns({
        container: selectors.tnsId,
        items: 3,
        slideBy: 3,
        controlsContainer: selectors.tnsCntrlsId,
        autoplay: true,
        autoplayTimeout: 3000,
        navPosition: 'bottom',
    });
}

The above approach will end up causing the tiny slider vendor javascript to be included in the main bundle and thus end up being loaded on all pages (even the one that don’t have a slider or a carousel). To mitigate this concern we can convert the above code to use the dynamic import as shown below:

if(tnsContainer) {
    /* Dynamic Import */
    import(
    `tiny-slider/src/tiny-slider`
    ).then(function({ tns }) {
        if (tns) {
            tns({
                container: selectors.tnsId,
                items: 3,
                slideBy: 3,
                controlsContainer: selectors.tnsCntrlsId,
                autoplay: true,
                autoplayTimeout: 3000,
                navPosition: 'bottom',
            });
        }
    })
    .catch(
        function(error) {
           console.error(error);
        }
    );
}

The above code will first check if the tnsContainer is defined, only then it will execute the import and later initiate the tiny slider. With this approach, for pages that don’t contain the carousel component we don’t incur the network latency or processing overhead caused by loading the 3rd party library unless it’s present on the page.

To learn more about how to use Dynamic Imports with Adobe Experience Manager& Webpack checkout the next article in this series here.


About Initialyze

Founded in 2015 in San Francisco, Initialyze specializes in providing software solutions and services to help worlds leading brands deliver transformation digital brand experiences. Our expertise includes Digital Strategy, Technology Implementation, Analytics and Marketing. We strive to form strong partnerships with our clients to envision, design and build innovative digital experiences efficiently and simply. Using an optimized implementation process and a suite of ready to use Initialyzers, we deliver on complex requirements quickly and cost effectively without sacrificing on quality.