Next.js: Dev Server Eagerly Compiles Dynamic Imports

Created on 5 Nov 2020  路  7Comments  路  Source: vercel/next.js

Bug report

Describe the bug

The dev server is eagerly following dynamic imports in a page and compiling them before they are requested.

One of my pages does one of a few dynamic imports depending on the type of object its viewing. Each dynamic import in the page is reasonably sized but put together they cover almost the entire codebase. Since the dev server is compiling them all on the first page load, just to build that page (even before the page loads and can do the import) the dev server takes about 2-3 minutes of compilation time and node racks up over 4gb of memory.

The bundle chunks are actually generated correctly both in dev and production, and the code isn't actually loaded by the browser until the dynamic import is called. However it seems the dev server has to compile or process the entire tree of dynamic imports just to display the page for the first time.

To Reproduce

Requesting this page responds in seconds:

export default function TinyPage() { return <div>Hello</div>; }

Whereas this page takes minutes, even though the dynamic import is never called:

import dynamic from 'next/dynamic';
const SomeBigComponent = dynamic(() => import('./some-big-component'), { ssr: false });

export default function TinyPage() { return <div>Hello</div>; }

Expected behavior

Dynamically imported files should not be compiled by the dev server until the client requests them.

Screenshots

Screen Shot 2020-11-04 at 3 28 05 PM

System information

  • OS: mac
  • Browser (if applies) chrome
  • Version of Next.js: 9.5.5
  • Version of Node.js: 12.13.1
story 3 stretch

All 7 comments

This is how dynamic imports work in webpack unfortunately. cc @sokra

I was afraid of that. Any idea if Webpack 5 changes this behavior? I can't find anything that specifically references it in their changelog.

Webpack will always compile dynamic imports at build time and that behavior will probably never change. On dev mode however the bundles are less optimized.

The name dynamic comes from the behavior of the imports, where the file is only imported on demand. In reality, there is not such thing as a dynamic export in Webpack (and probably most other bundlers). All exports are static, meaning they happen at build time.

It sounds like the only way to reduce load times is to reduce the amount of dynamic imports used by each page. I'll focus on splitting this very large page up into multiple smaller NextJS pages.

Thank you for your feedback! Closing this issue since the dev server load times are inherent to Webpack rather than NextJS.

Going to keep this open as we can potentially tackle it in the future.

FWIW this seems to be on the roadmap for Webpack 5.

This https://github.com/webpack/webpack/issues/8644 discussion has some interesting information. Including an npm package which I haven't tested, that defaults all dynamic imports to eager mode (no extra chunk). Obviously that should be used only for dev.

Ideally, if native support for webpackMode configuration is implemented that should be implementantion Next.js follows.

I don't think webpackMode: eager solves this issue.

Tagging an import as webpackMode: eager tells Webpack to always include the file in the current entry point rather than generate a separate chunk. Either way, Webpack is still parsing the dynamically imported file when the dev server starts.

The performance gains in the linked issue involve chunk-creation overhead, not the time necessary to actually parse the files that make up the chunk in the first place.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

knipferrc picture knipferrc  路  3Comments

pie6k picture pie6k  路  3Comments

olifante picture olifante  路  3Comments

wagerfield picture wagerfield  路  3Comments

DvirSh picture DvirSh  路  3Comments