DEV Community

Cover image for 🚀 Dynamic Imports (Code Splitting) | ES2020
Niall Maher
Niall Maher

Posted on

🚀 Dynamic Imports (Code Splitting) | ES2020

The ES2020 features were just approved by the TC39 committee, and in the proposal, you can import a file dynamically. What does that mean? Instead of having all your imports at the top of your file, you can import files as you need them and actually just load the data needed as it’s needed.

We have been doing this for a while with the help of Webpack or other build tools. Having it as a native feature will mean you won’t have to worry about the build tools and you can just focus on creating great applications.

In this video, we will refactor code so you can start using it today.

For more details scroll down. 👇

The static form is preferable for loading initial dependencies and can benefit more readily from static analysis tools and tree shaking.

Why dynamically import?

Static imports will slow down your application, by dynamically importing you can drastically speed up your load times. By not having one single large bundle you can archive crazy fast applications. This is known as "code splitting" as the code is delivered in smaller bundles as required.

Another reason you may want to dynamically import is if the module you are importing does not exist at load time.

How?

To dynamically import a module, the import keyword may be called as a function. When used this way, it returns a promise.

import('/modules/some-module.js')
  .then((module) => {
    // Now you can use the module here.
  });
Enter fullscreen mode Exit fullscreen mode

But for a much cleaner await keyword.

let module = await import('/modules/some-module.js');
Enter fullscreen mode Exit fullscreen mode

There are often times where you may never need to import a module (think of an unvisited page in a single page application). We can dynamically import based on user actions too which make dynamic importing super flexible.

Here's a sample of how you would dynamically load a module when the user clicks an element.

document.getElementById("button")
.addEventListener("click", async () => {
    const { app } = await import("./app.js");
    app();
});
Enter fullscreen mode Exit fullscreen mode

So it's that easy! This can drastically improve your user experience if you can build it into your workflow.

If you are looking for more information check out the MDN docs for Dynamic Importing.
🔗 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#Dynamic_Imports


Follow me on Twitter

Subscribe on Codú Community

Top comments (17)

Collapse
 
jwp profile image
John Peters

excelente, mi amigo!

Collapse
 
nialljoemaher profile image
Niall Maher

Gracias! 💜

Collapse
 
natterstefan profile image
Stefan Natter 🇦🇹👨🏻‍💻

Thanks Niall!

Collapse
 
nialljoemaher profile image
Niall Maher

No problemo! 🚀

Collapse
 
kryptand profile image
Kryptand

Hello Niall, thank you for that interesting article.

The example you posted would only be valid if you use the await in an async function context-
document.getElementById("button")
.addEventListener("click", async() => {
const { app } = await import("./app.js");
app();
});

Collapse
 
starboysharma profile image
Pankaj Sharma

I am wondering if a user clicks a button ten times which means we are going to import app.js each time. So, it will affect app performance or not? 😅🤔

Collapse
 
nialljoemaher profile image
Niall Maher

Good question, it will be available in the browser memory. By clicking it again you don't reload it. It's smart enough to know it has the bundle loaded so it will no longer need to be fetched from the web after the initial load. So it won't negatively affect your performance. 🚀

Thread Thread
 
gorvgoyl profile image
Gourav

are you sure? don't we need to check first for undefined and then load the module

if(!app)
{
app = await import("./app.js");
}

Thread Thread
 
nialljoemaher profile image
Niall Maher

You could wrap the whole thing in a try catch if you wanted some error checking. This is just a super simplified sample.

Thread Thread
 
gorvgoyl profile image
Gourav

no this is not about error checking.. if we check beforehand that the module is already loaded then we need not load it again

Thread Thread
 
nialljoemaher profile image
Niall Maher

Nope, run the code with the network tab open and you'll see it's only fetched once no matter how many times you click the button.

Thread Thread
 
gorvgoyl profile image
Gourav

got it, if that's the case then it's okay.

Collapse
 
nialljoemaher profile image
Niall Maher

Good catch! A typo on my behalf. Thank you 💜

Collapse
 
djamaile profile image
Djamaile

Can we already use this natively?

Collapse
 
nialljoemaher profile image
Niall Maher

There is some pretty good support already yes:
caniuse.com/#feat=es6-module-dynam...

Collapse
 
rcsm profile image
Rafael Cascalho

Wow, pretty cool! Nice article Niall, congrats :)

Collapse
 
nialljoemaher profile image
Niall Maher

Cheers Rafael!