Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Terser for minifying production build #5021

Closed
robinvdvleuten opened this issue Aug 23, 2018 · 8 comments · Fixed by #5083
Closed

Use Terser for minifying production build #5021

robinvdvleuten opened this issue Aug 23, 2018 · 8 comments · Fixed by #5083

Comments

@robinvdvleuten
Copy link

robinvdvleuten commented Aug 23, 2018

Feature request

Is your feature request related to a problem? Please describe.

Currently Next.js minifies the production build with Uglify. Unfortunately, uglify-es is no longer maintained and uglify-js does not support es6+ syntax very well. It would be nice to make the same move as Parcel to use the terser library.

Describe the solution you'd like

Webpack v4 has already a compatible terser plugin, which could be enabled quite easily;

// next.config.js
const TerserPlugin = require('terser-webpack-plugin')
const withSourceMaps = require('@zeit/next-source-maps')

module.exports = withSourceMaps({
  webpack: (config, { dev, isServer }) => {
    if (!dev && !isServer) {
      config.optimization.minimizer = [new TerserPlugin({
        parallel: true,
        sourceMap: true
      })]
    }

    return config
  }
})

I already did this on one of my projects which currently runs in production and haven't run into any issues yet. I even noticed some improvements on the build time. Also the sourcemaps work as expected.

Describe alternatives you've considered

An alternative would be to create a next-terser plugin to let people have the option to opt-in if they want.

@timneutkens
Copy link
Member

In your tweet you pointed out improved build times, could you provide data backing this up? Just curious about it, I definitely think we need to make this move 👍

@robinvdvleuten
Copy link
Author

The first run is the default Next.js webpack configuration (so it's using Uglify);

$ next build
[09:45:08] Compiling client
[09:45:08] Compiling server
> Using external babel configuration
> Location: "~/.babelrc"
[09:45:18] Compiled server in 10s
[09:47:16] Compiled client in 2m
✨  Done in 129.50s.

The second is with the terser webpack plugin enabled;

$ next build
[09:42:46] Compiling server
[09:42:46] Compiling client
> Using external babel configuration
> Location: "~/.babelrc"
[09:42:54] Compiled server in 8s
[09:43:36] Compiled client in 50s
✨  Done in 52.12s.

I am not that of an export of Babel / Webpack performance, but it can also be that there is some caching involved?

@robinvdvleuten
Copy link
Author

Hmm it seems if I run the build multiple times, the build times do not differ that much (+/- 5s).

@timneutkens
Copy link
Member

The best thing you can do when benchmarking is rm -rf .next && rm -rf node_modules/.cache && yarn build

@timneutkens
Copy link
Member

https://github.com/babel/minify#benchmarks you're right that it's faster

@robinvdvleuten
Copy link
Author

I've ran both builds again with my caches cleared, but the difference is in 2 or 3 seconds most of the time. So it's not that much faster. But if you look at projects like Parcel, it seems the way to go to minify es6 code with terser. Is there anything I can do to get terser into Next? As I mentioned, the config changes are not that hard and I have the time to create a PR for it to continue the discussion.

@timneutkens
Copy link
Member

Yeah the only thing you'll have to do is add the config you mentioned in the issue description.

@timneutkens
Copy link
Member

timneutkens commented Sep 1, 2018

This is the result for zeit.co production build:

Default webpack / Uglify:

rm -rf .next node_modules/.cache && yarn build
yarn run v1.7.0
$ yarn run buildonly && yarn run build:rss
$ cross-env NODE_ENV=production next build
[2:36:51 PM] Compiling client
[2:36:51 PM] Compiling server
> Using external babel configuration
> Location: "/Users/timneutkens/projects/front/.babelrc.js"
[2:37:46 PM] Compiled server in 55s
[2:39:12 PM] Compiled client in 2m
$ node ./.next/server/scripts/build-rss.js
Atom feed file generated at `./server/atom`
✨  Done in 145.19s.

Terser:

rm -rf .next node_modules/.cache && yarn build
yarn run v1.7.0
$ yarn run buildonly && yarn run build:rss
$ cross-env NODE_ENV=production next build
[2:42:22 PM] Compiling client
[2:42:22 PM] Compiling server
> Using external babel configuration
> Location: "/Users/timneutkens/projects/front/.babelrc.js"
[2:43:20 PM] Compiled server in 57s
[2:44:42 PM] Compiled client in 2m
$ node ./.next/server/scripts/build-rss.js
Atom feed file generated at `./server/atom`
✨  Done in 143.70s.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants