Webpack: Taking a long time to build

In my case I updated devtool property to false.


As discussed in the comments, here are the most obvious changes you could make to speed up your build:

  • UglifyJsPlugin and ExtractTextPlugin are very heavy in terms of their impact on your compilation time, while not actually presenting many tangible benefits in development. Check process.env.NODE_ENV in your config script, and enable/disable them depending on whether you're doing a production build or not.
    • In place of ExtractTextPlugin, you can use style-loader in development to inject CSS into the head of the HTML page. This can cause a brief flash of unstyled content (FOUC) when the page loads, but is much quicker to build.
  • If you're not already, use webpack-dev-server rather than just running Webpack in watch mode - using the dev server compiles the files in memory instead of saving them to disk, which further decreases the compile times in development.
    • This does mean you'll have to manually run a build when you want to have the files written to disk, but you'll need to do that to switch to your production config anyway.
  • Not sure if this has any impact on performance, but the resolve section of your config doesn't meaningfully differ from the defaults, and you should be able to remove it without causing any issues.

Article on Medium: https://medium.com/@gagan_goku/hot-reloading-a-react-app-with-ssr-eb216b5464f1

Had to solve the same problem for my React app (HELO) with SSR. Things get complicated with SSR, but thankfully webpack gets a lot faster if you specify --mode=development, because it does it in memory.

webpack-dev-server did not work for me because I need the client.js bundle for the SSR client to work properly. Here's my setup:

webpack.config.js:

const path = require('path');

module.exports = {
    entry: {
        client: './src/client.js',      // client side companion for SSR
        // bundle: './src/bundle.js',      // Pure client side app
    },
    output: {
        path: path.resolve(__dirname, 'assets'),
        filename: "[name].js"
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                include: path.resolve(__dirname, 'src'),
                loader: "babel-loader",
                options: {
                    presets: [
                        '@babel/preset-env',
                        {'plugins': ['@babel/plugin-proposal-class-properties']},
                    ],
                }
            }
        ]
    },
    watchOptions: {
        aggregateTimeout: 1000,
        poll: 500,
        ignored: /node_modules/,
    }
};

package.json:

  "scripts": {
    // IMP: --mode=development
    "run-dev-ssr": "webpack --config webpack.config.js --watch --mode=development & babel src -d dist --watch & browser-refresh dist/server.js"
  }

.browser-refresh-ignore:

node_modules/
static/
.cache/
.*
*.marko.js
*.dust.js
*.coffee.js

.git/

# Add these files to ignore, since webpack is storing the compiled output to assets/ folder
src/
dist/

Build times without mode:

Hash: 81eff31301e7cb74bffd
Version: webpack 4.29.5
Time: 4017ms
Built at: 05/10/2019 9:44:10 AM

Hash: 64e10f26caf6fe15068e
Version: webpack 4.29.5
Time: 2548ms


Time: 5680ms
Time: 11343ms

Build times with mode:

Hash: 27eb1aabe54a8b995d67
Version: webpack 4.29.5
Time: 4410ms

Time: 262ms

Time: 234ms

Time: 162ms