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

Slow compilation still after upgrade to new version 4.0.1 #10154

Open
dagar07 opened this issue Nov 26, 2020 · 42 comments
Open

Slow compilation still after upgrade to new version 4.0.1 #10154

dagar07 opened this issue Nov 26, 2020 · 42 comments

Comments

@dagar07
Copy link

dagar07 commented Nov 26, 2020

This issue has been fixed in 4.0.1.
https://github.com/facebook/create-react-app/releases/tag/v4.0.1

The performance is much, much better now! Thank you! ❤🎉

This issue did not fix yet, still take around 30s to 40s to recompile the changes after a small change in the files

Originally posted by @raRaRa in #9966 (comment)

@dagar07 dagar07 changed the title This issue has been fixed in 4.0.1. Slow compilation still after upgrade to new version 4.0.1 Nov 26, 2020
@andrwo
Copy link

andrwo commented Nov 26, 2020

I concur. I have upgraded to 4.0.1 (using Typescript 4.1.2).

Initial compile times are better.

But each time I modify a single tsx file, the diff re-"Compiling..." cycle is taking way longer than pre v4. Previously it takes around 2-3 seconds to reflect in browser, now it takes upwards of 15 seconds.

I tried with both setting in .env file FAST_REFRESH = true and false, no difference.

@eek
Copy link

eek commented Nov 26, 2020

I have the same issue. Extremely slow compile and recompile times.

I tried measuring the compile time with https://github.com/stephencookdev/speed-measure-webpack-plugin to see what's so slow.

This is my benchmark:

image

Unfortunately I couldn't run it on re-compile after a file update because apparently it breaks. Might have something to do with stephencookdev/speed-measure-webpack-plugin#44

But, it's extremely slow lol. And also the discussions (like this - #9909) aren't very helpful

@ahrbil
Copy link

ahrbil commented Nov 26, 2020

Did you guys notice any slow build time as well?
I can't even build our app on CI as it is always failing due to time out after upgrading to both v4.0.0 and v4.0.1

@jamiehaywood
Copy link

@ahrbil could you detail your issues some more about the CI? I encountered the same issue today. Build keeps timing out (even though it's already built the static files!):
image

@maxsbelt
Copy link
Contributor

maxsbelt commented Nov 26, 2020

I tried to debug my app using speed-measure-webpack-plugin (thanks @eek for suggestion) and figured out that problem is 100% (at least in my case) related to ESLintPlugin. Here some metrics:

version 3.4.4 version 4.0.1 version 4.0.1 (second run) version 4.0.1 without ESLintPlugin
Screenshot 2020-11-26 at 20 20 59 Screenshot 2020-11-26 at 20 24 34 Screenshot 2020-11-26 at 20 25 31 Screenshot 2020-11-26 at 20 26 32

You can try if it works in your case by commenting out the plugin in node_modules/react-scripts/config/webpack.config.js:

Screenshot 2020-11-26 at 20 45 21

As a temporary solution you can use react-app-rewired with such config-override:

module.exports = (config) => {
  config.plugins = config.plugins.filter(
    (plugin) => !(plugin.options && plugin.options.eslintPath)
  );
  return config;
};

@ejose19
Copy link

ejose19 commented Nov 27, 2020

@maxsbelt Thanks, the speeds after that change are amazing, just a couple of seconds for initial compilation and 1s for recompilation. Here's a patch for those using patch-package

diff --git a/node_modules/react-scripts/config/webpack.config.js b/node_modules/react-scripts/config/webpack.config.js
index eddca1b..954abe9 100644
--- a/node_modules/react-scripts/config/webpack.config.js
+++ b/node_modules/react-scripts/config/webpack.config.js
@@ -750,7 +750,7 @@ module.exports = function (webpackEnv) {
           // The formatter is invoked directly in WebpackDevServerUtils during development
           formatter: isEnvProduction ? typescriptFormatter : undefined,
         }),
-      new ESLintPlugin({
+      isEnvProduction && new ESLintPlugin({
         // Plugin options
         extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'],
         formatter: require.resolve('react-dev-utils/eslintFormatter'),

@dagar07
Copy link
Author

dagar07 commented Nov 27, 2020

I tried to debug my app using speed-measure-webpack-plugin (thanks @eek for suggestion) and figured out that problem is 100% (at least in my case) related to ESLintPlugin. Here some metrics:

version 3.4.4 version 4.0.1 version 4.0.1 (second run) version 4.0.1 without ESLintPlugin
Screenshot 2020-11-26 at 20 20 59 Screenshot 2020-11-26 at 20 24 34 Screenshot 2020-11-26 at 20 25 31 Screenshot 2020-11-26 at 20 26 32
You can try if it works in your case by commenting out the plugin in node_modules/react-scripts/config/webpack.config.js:

Screenshot 2020-11-26 at 20 45 21

As a temporary solution you can use react-app-rewired with such config-override:

module.exports = (config) => {
  config.plugins = config.plugins.filter(
    (plugin) => !(plugin.options && plugin.options.eslintPath)
  );
  return config;
};

Not worked for me

@JanJakes
Copy link

May be related to #10119.

@ahrbil
Copy link

ahrbil commented Nov 27, 2020

@ahrbil could you detail your issues some more about the CI? I encountered the same issue today. Build keeps timing out (even though it's already built the static files!):
image

@jamiehaywood
it's the same issue we are facing too
image

@eek
Copy link

eek commented Nov 27, 2020

@JanJakes that's true, the issue seems to be related to threads: false.

I've added that to the ESLintPlugin options and now it's fast compiling again.

I've tested it with overriding the config. If you have craco or react-app-rewired you can test it with:

overrideWebpackConfig: ({ webpackConfig }) => {
    webpackConfig.plugins = webpackConfig.plugins.filter(
        (plugin) => !(plugin.options && 'eslintPath' in plugin.options)
    );

    webpackConfig.plugins.unshift(new ESLintPlugin({
        // Plugin options
        extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'],
        formatter: require.resolve('react-dev-utils/eslintFormatter'),
        eslintPath: require.resolve('eslint'),
        context: './src',
        cache: true,

		// Setting threads to false boost compiling speed back to previous levels
        threads: false,

        // ESLint class options
        cwd: fs.realpathSync(process.cwd()),
        resolvePluginsRelativeTo: __dirname,
        baseConfig: {
            extends: [require.resolve('eslint-config-react-app/base')],
            rules: {
                'react/react-in-jsx-scope': 'error',
            },
        },
    }));

    return webpackConfig;
}

replace overrideWebpackConfig: ({ webpackConfig }) => { with module.exports = (webpackConfig) => { for react-app-rewired

cc - webpack-contrib/eslint-webpack-plugin#50 (comment)
cc - #10119

@dagar07
Copy link
Author

dagar07 commented Nov 27, 2020

@eek I have done the same thing and but it's not working

@eek
Copy link

eek commented Nov 30, 2020

@eek I have done the same thing and but it's not working

@dagar07 try this:

ADD:

  "resolutions": {
    "react-scripts/eslint-webpack-plugin": "2.3.0"
  }

at the end of the package.json file and then write yarn for it to install with the proper resolution. Should work fast afterwards.

@dagar07
Copy link
Author

dagar07 commented Dec 1, 2020

@eek I have done the same thing and but it's not working

@dagar07 try this:

ADD:

  "resolutions": {
    "react-scripts/eslint-webpack-plugin": "2.3.0"
  }

at the end of the package.json file and then write yarn for it to install with the proper resolution. Should work fast afterwards.

I have added yarn module and using the yarn now, but not working ... with recompile

@MaximeBernard
Copy link

Thanks @maxsbelt, commenting ESLintPlugin helped my compile time from 32s to 16s. My yarn start recompile time is almost instantaneous. You made my developer experience great again 😄

@jamiehaywood
Copy link

for anyone that is using CRA 4.0.1 in a monorepo (using lerna) - add:

  "resolutions": {
    "react-scripts/eslint-webpack-plugin": "2.3.0"
  }

to the root package.json and it should fix the slow reloading issues.

@eek
Copy link

eek commented Dec 6, 2020

for anyone that is using CRA 4.0.1 in a monorepo (using lerna) - add:

  "resolutions": {
    "react-scripts/eslint-webpack-plugin": "2.3.0"
  }

to the root package.json and it should fix the slow reloading issues.

@jamiehaywood It was fixed in eslint-webpack-plugin 2.4.1

@ejose19
Copy link

ejose19 commented Dec 8, 2020

@PraveenVerma17 As I'm using npm and can't pin eslint-webpack-plugin, I'm using the change stated by @eek which works correctly

diff --git a/node_modules/react-scripts/config/webpack.config.js b/node_modules/react-scripts/config/webpack.config.js
index eddca1b..8652fc3 100644
--- a/node_modules/react-scripts/config/webpack.config.js
+++ b/node_modules/react-scripts/config/webpack.config.js
@@ -757,6 +757,7 @@ module.exports = function (webpackEnv) {
         eslintPath: require.resolve('eslint'),
         context: paths.appSrc,
         cache: true,
+        threads: false,
         // ESLint class options
         cwd: paths.appPath,
         resolvePluginsRelativeTo: __dirname,

@ejose19
Copy link

ejose19 commented Dec 8, 2020

@PraveenVerma17 Are you using react-scripts v4.0.1?

@eek
Copy link

eek commented Dec 9, 2020

@PraveenVerma17 just delete the node_modules folder and install again, it should automatically install the latest eslint-webpack-plugin which no longer has the issue.

@ejose19
Copy link

ejose19 commented Dec 9, 2020

@eek Correct, there's no longer need for a patch as it works correctly on eslint-webpack-plugin v2.4.1, however if they're using npm and already had a package-lock.json it won't update the version even after deleting node_modules and installing again. @PraveenVerma17 What you need to do is, remove the patch and run npm uninstall react-scripts && npm install -D react-scripts so you actually get the latest version.

@benduran
Copy link

Hi folks 👋
Wanted to chime in and say that I'm glad to see there's discussion around this issue. I've recently attempted an upgrade to a few applications. Some applications build fine, but are noticeably slower. One application hangs almost indefinitely, and pegs my disk I/O at 100% usage, rendering my system nearly unusable. The last stable version of CRA3.X worked like a charm, no issues.

@emersonlaurentino
Copy link

using resolutions worked correctly for me, btw thanks @eek and @jamiehaywood

"resolutions": {
  "react-scripts/eslint-webpack-plugin": "2.4.1"
}

@dagar07
Copy link
Author

dagar07 commented Jan 6, 2021

@eek I have updated to "eslint-webpack-plugin": "^2.4.1", but its not solve,
Please help me to fix this

@jarretmoses
Copy link

Is there an update with this issue? 4.x is still unusable for me as compile times are way too long. Especially the initial startup. Im all up to date versioning have cleared my node modules, followed other suggestion but everything is still extremely slow.

@fo-fo
Copy link

fo-fo commented Jan 30, 2021

Our initial startup time has gone from ~40s (react-scripts 3.4.0) to ~3m30s (react-scripts 4.0.1), a 5x increase.

EDIT: Disabling ESLintPlugin brings it down to around 1m20s, but still not very happy about it 😕 (2x increase)

@andrwo
Copy link

andrwo commented Feb 6, 2021

Anyone tried if the 4.0.2 update that just dropped fixes this issue?

@xfournet
Copy link

xfournet commented Feb 6, 2021

@andrwo yes the DISABLE_ESLINT_PLUGIN option fix my compilation speed problem (i have my own setup of eslint). See #10170

@leojh
Copy link

leojh commented Feb 9, 2021

at least for us it improved start substantially. it's now back to about the same it was before CRA 4.

@stclairdaniel
Copy link

I'm still getting quite slow start and lint speeds on react-scripts 4.3.0, even with

"resolutions": {
  "react-scripts/eslint-webpack-plugin": "2.4.1"
}

@Tiberriver256
Copy link

Resolutions resolved the issue for me on initial build time

@Jayaramstarr
Copy link

@JanJakes that's true, the issue seems to be related to threads: false.

I've added that to the ESLintPlugin options and now it's fast compiling again.

I've tested it with overriding the config. If you have craco or react-app-rewired you can test it with:

overrideWebpackConfig: ({ webpackConfig }) => {
    webpackConfig.plugins = webpackConfig.plugins.filter(
        (plugin) => !(plugin.options && 'eslintPath' in plugin.options)
    );

    webpackConfig.plugins.unshift(new ESLintPlugin({
        // Plugin options
        extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'],
        formatter: require.resolve('react-dev-utils/eslintFormatter'),
        eslintPath: require.resolve('eslint'),
        context: './src',
        cache: true,

		// Setting threads to false boost compiling speed back to previous levels
        threads: false,

        // ESLint class options
        cwd: fs.realpathSync(process.cwd()),
        resolvePluginsRelativeTo: __dirname,
        baseConfig: {
            extends: [require.resolve('eslint-config-react-app/base')],
            rules: {
                'react/react-in-jsx-scope': 'error',
            },
        },
    }));

    return webpackConfig;
}

replace overrideWebpackConfig: ({ webpackConfig }) => { with module.exports = (webpackConfig) => { for react-app-rewired

cc - webpack-contrib/eslint-webpack-plugin#50 (comment)
cc - #10119

Can you tell me the file and the file path where to set this?

@ivanviskovic
Copy link

Also very slow build time. When i tried to debug it with speed-measure-webpack-plugin but could not find anything.
Screenshot 2021-07-05 at 12 40 13

Anyone have any idea what might be the problem?

@SamKirkland
Copy link

Root Problem in my case

Create React App uses CaseSensitivePathsPlugin and IgnorePlugin. In my case replacing these two plugins with alternatives reduced my dev environment build time from 14 minutes to 3 minutes. I did a bit of research and it appears these two plugins account for 60-80% of the build time for other projects on github. So I figured I would leave instructions here on how to implement these changes. I would like to put together a PR for these changes, so please leave feedback and I'll make a PR if all goes well with others.

Notes about these changes

The CaseSensitivePathsPlugin is already disabled on the production build. Which means these changes mostly help the dev build. These changes worked for me. But that does not mean they will work for you. Please run the speed-measure-webpack-plugin before making these changes. Also if these changes do fix your build issues please leave a comment with before/after timings or feedback so I can put together a Pull Request.

That being said I think this change could help a few people:

Testing these changes on the largest CRA project I've contributed to (AppSmith) made the following changes.

Before (8 minutes)

image

After (2.2 minutes)

image

^ timings are averages over 3 runs

Solution

We are going to replace both the CaseSensitivePathsPlugin and IgnorePlugin plugins. To do so we need craco to make modification to CRA webpack config without ejecting.

Craco config

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const MomentLocalesPlugin = require("moment-locales-webpack-plugin");

module.exports = {
    plugins: [
        {
            plugin: {
                overrideWebpackConfig: ({ webpackConfig }) => {
                    // remove CaseSensitivePathsPlugin (replace with tsconfig setting or eslint setting)
                    webpackConfig.plugins = webpackConfig.plugins.filter(
                        (plugin) => plugin.constructor.name !== "CaseSensitivePathsPlugin"
                    );

                    // remove IgnorePlugin
                    webpackConfig.plugins = webpackConfig.plugins.filter(
                        (plugin) => plugin.constructor.name !== "IgnorePlugin"
                    );
                    // add new ContextReplacementPlugin via moment-locales-webpack-plugin
                    webpackConfig.plugins.push(new MomentLocalesPlugin()); // exclude all locales except en
            
                    const smp = new SpeedMeasurePlugin({
                        outputFormat: "humanVerbose",
                        loaderTopFiles: 5,
                    });
        
                    return smp.wrap(webpackConfig);
                },
            }
        }
    ]
};

What is case-sensitive-paths-webpack-plugin doing?

See the code in CRA webconfig
Why does this plugin exist, well looking at the github history it adds checks for NTFS (windows) vs. APFS (mac) file systems. If all your machines are on a single OS, including build servers you could remove this plugin.

However I want to keep it around just in case someone on my team develops on another OS. One option is to use ESLint instead with the eslint-plugin-import plugin and its caseSensitive option. Or if you are using typescript remove the plugin and enable the tsconfig option forceConsistentCasingInFileNames which will do the same thing in a fraction of the time - this is what I did. Note: I need to do some more testing to verify ESLint/Typescript are doing the equivalent checks. One concern I have is these alternatives are not recursively checking the dir tree.

What is IgnorePlugin doing?

See the code in CRA webconfig
This configuration of the IgnorePlugin helps reduce the bundle size when using moment js. However swapping it out with the newer ContextReplacementPlugin improves performance dramatically.

Maintainer for Performance?

@gaearon / @Timer / @ianschmitz Any thoughts on adding a maintainer for performance related issues. As you know perf issues are normally the last priority so there might be some value in a dedicated perf maintainer. (related #8096 (comment))

@FezVrasta
Copy link
Contributor

FezVrasta commented Oct 3, 2021

I just tested the above suggestions and I couldn't observe any performance difference at all in my setup. I'm on macOS Big Sur on a Late 2014 iMac 5k (3.5 GHz Quad-Core Intel Core i5)

What I noticed is that InjectManifest plugin takes almost 7 seconds to run. It seems a lot, maybe something can be done to optimize it.

@Mathieuu
Copy link

Mathieuu commented Jan 6, 2022

For our project, the performance gain is dramatic. I followed SamKirkland comment and simply filtered CaseSensitivePathsPlugin and IgnorePlugin
plugin. (Macbook pro 2019 i9 8core with 32GB of ram, yarn running directly in mac os)

Before/After

Screen Shot 2022-01-05 at 6 06 03 PM

Screen Shot 2022-01-05 at 6 05 50 PM

@rkhaslarov
Copy link

In out case it's babel-loader
SMP ⏱
General output time took 71,230 ms

SMP ⏱ Loaders
@pmmmwh/react-refresh-webpack-plugin, and
babel-loader took 58,561 ms

OR even

@pmmmwh/react-refresh-webpack-plugin, and
babel-loader took 1,062,270 ms

did anyone faced the issue?

@suraj-adewale
Copy link

Hi everyone,
I had similar experience, however I was able to fix it with following steps:

  1. I create a new react app. npx create-react-app my-app
  2. I tested npm start and it was running faster.
  3. I now compared package.json of my-app with my existing project
  4. I updated package.json of my exiting project(slow) with "react": "^18.1.0", "react-dom": "^18.1.0", "react-scripts": "5.0.1",
  5. Then npm install. Done. Try this and let me hear your feedback

@jonnycbw
Copy link

jonnycbw commented May 22, 2022

@suraj-adewale

Hi everyone,

I had similar experience, however I was able to fix it with following steps:

  1. I create a new react app. npx create-react-app my-app

  2. I tested npm start and it was running faster.

  3. I now compared package.json of my-app with my existing project

  4. I updated package.json of my exiting project(slow) with "react": "^18.1.0", "react-dom": "^18.1.0", "react-scripts": "5.0.1",

  5. Then npm install. Done. Try this and let me hear your feedback

Unfortunately this didn't work for me, we ended up regressing back to react-scripts 3.4.3, where it's still slow but not as slow as 4.0.1 or 5.0.1. I'm gonna give the craco solution a try to see if that helps at all.

In our case we have multiple packages but not in a monorepo, just yarn linked. We're not fussed so much about build times but more about recompile time after making changes (hmr)

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

No branches or pull requests