Next.js: Slow Next.js production build process (Next 7, 8)

Created on 16 Feb 2019  Â·  11Comments  Â·  Source: vercel/next.js

Bug report

Hey everyone,

I have a Next.js app which I'm serving from a dedicated server machine.
The build takes up to one minute and a half when deploying a new version.

Are there any recommended practices to minimize this time or ways to figure out what's going on?

I'm using yarn build (which calls next build) to build the app, and my build.sh also sets export NODE_ENV=production prior to building.

I'm using the WebpackBar plugin with this configuration:

{
    fancy: true,
    profile: true,
    basic: false,
}

Most time is spent at: additional chunk assets processing (91%).

Number of pages served: fewer than 20.

Any clues? I get very fast build times for individual pages I'm editing during development, and yarn dev doesn't take more than 10 seconds to start up on my dev machine.

yarn build however takes 40 seconds on the dev machine.

These times just get longer on the weaker production machine.

System information

  • OS: Windows 10, CentOS 7
  • Version of Next.js: 8.0.1

    • Dev machine: SSD, i7 7th gen 2.8GHz, 8GB RAM

    • Production machine: HDD, Xeon, 2.5GHz 4GB RAM

Dependencies

"@material-ui/core": "^3.9.2",
"@material-ui/icons": "^3.0.2",
"@material-ui/styles": "^3.0.0-alpha.10",
"auth0-js": "^9.10.0",
"auth0-lock": "^11.14.0",
"axios": "^0.18.0",
"compression": "^1.7.3",
"date-fns": "^1.30.1",
"dotenv": "^6.2.0",
"dotenv-webpack": "^1.7.0",
"downshift": "^3.2.2",
"express": "^4.16.4",
"jss": "^9.8.7",
"next": "^8.0.1",
"nprogress": "^0.2.0",
"purify-ts": "^0.12.2",
"react": "^16.8.2",
"react-dom": "^16.8.2",
"react-jss": "^8.6.1",
"react-stripe-elements": "^2.0.3",
"recharts": "^1.5.0"

Config:

webpack: (config) => {
    config.plugins.push(new Dotenv({
        path: path.join('.env.public'),
    }));
    config.plugins.push(new WebpackBar({
        fancy: true,
        profile: true,
        basic: false,
    }));
    config.resolve.extensions = ['.js', '.jsx'];
    return config
},

All 11 comments

Can you show your project structure, do you have components in the pages directory?

Hi @timneutkens, thanks for the quick reply.

My pages/ directory has strictly the components that correspond to routes.

I'm transpiling TypeScript to JS/X in place, so for each .js/x file there's a .ts/x file from which it gets transpiled, but I expect that these should get ignored by the configuration.

Here's the tree:

├───next-mui
├───pages
├───src
│   ├───auth
│   ├───components
│   │   ├───pages
│   │   │   ├───callback
│   │   │   └───subscribe
│   │   │       └───payment
│   │   └───profile
│   ├───layout
│   └───remote
└───static
    └───images
        └───icons

I guess it's the minifier (terser) being slow, it's hard to say without a clear reproduction.

You're right, I checked the output of the WebpackBar plugin and it did mention TerserPlugin at the last stage, the one taking the longest.

chunk asset optimization (92%) TerserPlugin

But I discovered something: while I did not have components under pages/ I did have a garbage folder with obsolete and broken route components that I deleted when building the tree structure above.

And since then, the build times are consistently under 10 seconds on both the dev and production machine. Do you suspect it has to do with those error-ridden components?

@dandrei it's hard to say without seeing what was actually there, but glad it was resolved 🙏

In Next.js 8 we introduced a step at the end of the build process that logs out all the pages that were built to give you a visual indication of having routes there that shouldn't be routes.

Going to close this as it was solved.

image

@timneutkens How to disable Terser ?

Edit

Looks like enabling the cache will actually break SSR in Next.js. Disregard the suggestion I offered below.


@AliasT have you tried using a cache for Terser?

In your next.config.js:

 module.exports = {
     webpack: (config) => {
         //
         // your other configuration options
         //
         config.optimization = {
             minimizer: [
                 new TerserPlugin({
                     cache: true
                 }),
             ],
         };
         return config;
     },
 };

The cache parameter can also be a path, if you don't want the cache to reside in the default node_modules/.cache/terser-webpack-plugin/.

For Windows paths, you also need to use regular slashes (So it would be something like C:/temp/)

Caching is enabled by default. It's generally not recommended to edit the webpack config, especially this part of the webpack config.

config.optimization.minimize = false disables terser.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jesselee34 picture jesselee34  Â·  3Comments

wagerfield picture wagerfield  Â·  3Comments

formula349 picture formula349  Â·  3Comments

lixiaoyan picture lixiaoyan  Â·  3Comments

knipferrc picture knipferrc  Â·  3Comments