How to lazily load modules in Next.js applications
Being able to analyze the bundled software visually is very useful because we can optimize the application very easily.
Suppose we need to load the Moment library in a blog post. run:
npm install moment
Include it in the project.
Now let us simulate the fact that we need to use it in two different routes:/blog
with/blog/[id]
.
We import itpages/blog/[id].js
:
import moment from 'moment'
…
const Post = props => {
return (
<div>
<h1>{props.post.title}</h1>
<p>Published on {moment().format(‘dddd D MMMM YYYY’)}</p>
<p>{props.post.content}</p>
</div>
)
}
Let me take today’s date as an example.
As you can see, it will include Moment.js in the blog post page bundle.npm run analyze
:
See that we now have a red entry/blog/[id]
, Is the route we added Moment.js!
It changed from ~1kB to 350kB, which is a large number. This is because the Moment.js library itself is 349kB.
Now, the customer bundle visualization shows us that larger bundles are the first page, which used to be very few. And 99% of its code is Moment.js.
Every time a blog post is loaded, we will transmit all this code to the client. This is not ideal.
One solution is to find a smaller library, because Moment.js is not known for its lightweight (especially out of the box, including all locales), but let's assume that for the sake of example, we have to use it .
Instead, what we can do is to separate all Moment codes into oneSeparate bundle.
how is it? Instead of importing Moment at the component level, an asynchronous import is performed internallygetInitialProps
, And then we calculate the value to be sent to the component. Remember, we can’tgetInitialProps()
The returned object, so we calculate the date in it:
import posts from '../../posts.json'
const Post = props => {
return (
<div>
<h1>{props.post.title}</h1>
<p>Published on {props.date}</p>
<p>{props.post.content}</p>
</div>
)
}
Post.getInitialProps = async ({ query }) => {
const moment = (await import(‘moment’)).default()
return {
date: moment.format(‘dddd D MMMM YYYY’),
post: posts[query.id]
}
}
export default Post
Saw that special call.default()
Rearawait import
? The default export needs to be referenced in the dynamic import (seehttps://v8.dev/features/dynamic-import)
Now if we runnpm run analyze
Again, we can see:
our/blog/[id]
The package is again small because Moment has moved to its own package file and loaded separately by the browser.
Download mine for freeNext.js manual
More tutorials next:
- Getting started with Next.js
- Next.js vs Gatsby vs create-react-app
- How to install Next.js
- Use links to link two pages in Next.js
- Dynamic content in Next.js in the router
- Use getInitialProps to feed data to Next.js components
- Use CSS to style Next.js components
- Prefetch content in Next.js
- Use a router to detect active links in Next.js
- Check the source code to confirm that SSR is working properly in Next.js
- Next.js: Fill the head tag with a custom tag
- Deploy the Next.js application now
- Next.js: Only run code on the server or client side of Next.js
- Deploy Next.js application in production
- How to analyze Next.js application bundles
- Lazy loading module in Next.js
- Add a wrapper component to your Next.js application
- Add Next.js to the icon in your application
- Next.js application bundle
- How to use Next.js router
- How to use Next.js API routing
- How to get cookies on the server side in Next.js application
- How to change the Next.js application port