Exploring Dynamic Imports in Next.js

Weian Wang
JavaScript in Plain English
3 min readMar 5, 2021

--

Why should we do dynamic import

Nowadays we use tools like webpack to bundle our JavaScript, it makes all our JavaScript into one bundle.js file. It saves us a lot of work. But the problem is this file can be huge while modern website is getting more and more complex. When Browsers deal with this huge bundle.js file, loading time can be long enough to drive users away. We definitely don’t want that happen when user is literally everything to a website.

To avoid this happen we want to load modules separately. When the page first render all modules are loaded in the same time no matter it is needed or not. Now we want to load modules when we actually need it. It’s called code-splitting. With dynamic import we can easily apply code-splitting to our project.

JavaScript Solution

In general we import modules like below:

Import Sample from ‘./Sample’

This is static import. However since ES6, keyword ‘import’ started to support dynamic import by calling a function which returns a promise.

import(‘./Sample’).then(( Sample )=>{ });

And it also support keyword await.

let Sample = await import(‘./Sample’);

If you are using Create React App or Next.js, this feature is available for you right away. But not to those who configured their own project. They have to configure more stuffs following official guides from webpack.

React Solution

Since this feature is not strong enough, React provides us other solutions : React.lazy and Suspense. It’s quite easy to learn. First, we call a function in React.lazy(), and do dynamic import in it. Then we assign React.lazy() to a variable. That’s it, the component is already imported and ready to be rendered. Then this is when we need Suspense. We wrap the component with Suspense. It provides a fallback prop. The contents we pass to fallback prop will render while waiting for the component importing.

React.lazy and Suspense

These are awesome feature but not available with SSR(Server-Side Rendering). React officially recommend Loadable Components as SSR(Server-Side Rendering) solution. You can check it on GitHub.

Next.js solution

We are finally getting to the point. Next.js provides us ‘next/dynamic’ which solves all the problems we mentioned above. And it can do even more.

Basic use is just like the way we did with import().

next/dynamic

It also provides a feature like React Suspense which we just introduced above. Add a ‘loading’ component into dynamic(). It renders message when component is being loaded. Just pass what you want to show into ‘loading’.

next/dynamic with loading

All these are done with SSR(Server-Side Rendering). It’s awesome, save us lot of works. But what if we don’t want to do dynamic import with SSR(Server-Side Rendering)? Actually this kind of situation happen a lot. When we want to use package from npm. We first download it, then we have to import modules from this package to our component. And you might get an error : “window is not defined”, like below :

This is because window object only available in browsers. It doesn’t exist in server side. And there are a lot of packages using window object. To avoid this error, we shouldn’t do dynamic import with SSR(Server-Side Rendering). To turn it off, all we have to do is add a simple object into dynamic().

next/dynamic without ssr

By the way Next.js supports import() for JavaScript. You can use it just like the way we do it without Next.js. The difference is in Next.js, it also work with SSR(Server-Side Rendering).

Conclusion

With ‘next/dynamic’ we can handle dynamic import in all scenarios. If you are using Next.js with your React project and haven’t know it yet, you better catch up!

--

--