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

Speed up npm run build #913

Closed
ivosabev opened this issue Oct 16, 2016 · 29 comments
Closed

Speed up npm run build #913

ivosabev opened this issue Oct 16, 2016 · 29 comments

Comments

@ivosabev
Copy link

This is not a bug, but more like a request to speed up the build times. Even on a clean project it takes a good 15 seconds to build and on a medium-sized project it goes to 3-4 minutes. Any effort in this direction will be greatly appreciated.

Thanks!

@gaearon
Copy link
Contributor

gaearon commented Oct 16, 2016

It's most likely due to linting. We should enable cache for ESLint loader because I think it's disabled right now.

If you could supply a larger project reproducing it, that would be helpful for figuring out the root cause.

@thien-do
Copy link
Contributor

thien-do commented Oct 17, 2016

@gaearon I can supply a real life large project (a trading app), which takes about 3 minutes to build. However, it uses a fork react-scripts. Can it help?

@gaearon
Copy link
Contributor

gaearon commented Nov 20, 2016

@dvkndn Yea it would be helpful.

@godmar
Copy link

godmar commented Dec 1, 2016

Would like to second @ivosabev 's request.

On a 2-core, 2GB Digital Ocean instance, npm run build on a null-CRA 0.7.0 project takes 11s.
It takes similarly long for the webpack dev server to start.

Adding 15-20 .js files for components, etc. expands this to 20s.

I'm not sure whether CRA is to blame, though - I've seen similarly catastrophic build times in other projects with similar, but indepedently created webpack configurations.

@gaearon
Copy link
Contributor

gaearon commented Dec 1, 2016

Can you debug why this happens? I don’t have the time to look into it right now. But if you put a few logs here and there you’ll likely see the overall picture of where the time is being spent.

As I noted above it might help to enable caching for ESLint loader. Have you tried this?

@godmar
Copy link

godmar commented Dec 3, 2016

A big contributor is UglifyJSPlugin. Disabling it reduces the build time for an empty project from 11.9s to 6.7s on my machine (that's 44%).

Removing eslint from preloaders, by contrast, reduces the build time from 11.9s to 10.5s (that's 11%).

@godmar
Copy link

godmar commented Dec 3, 2016

I tried your idea by setting 'cache: true' in the eslint config.
This shaved about .5s of subsequent runs (provided no files were changed.)
Only src/index.js and src/App.js made it into the cache (for an empty project).

For non-empty project (2,249 lines of JavaScript in 45 files)
Build time: 66s
Build time without UglifyJS plugin: 27s
Build time without eslint: 62s
Build time on 2nd and subsequent builds when eslint cache turned on: 61s
Time between npm start and development server reporting ready: 16s

This is what the early 1990s were like when we waited for our TurboPascal or TurboC project to compile on our 80386 33 MHz desktops. It kind of takes the fun out of development, especially considering that we're using a language that fundamentally shouldn't need any compilation.

The only redeeming fact here is that a hot rebuild (touching a .js file) takes "only" 4-5 seconds - as long as HMR doesn't get stuck. Although even that is hampered by the fact that I usually make changes to multiple .js files when developing (2-3 files), and each file save triggers a separate rebuild, so a total of 12-15s.

I'm seeing similarly abysmal performance with webpack 1.x on a project that doesn't use CRA, so I don't think CRA is to blame. Are you not seeing that?

@gaearon
Copy link
Contributor

gaearon commented Dec 5, 2016

It kind of takes the fun out of development, especially considering that we're using a language that fundamentally shouldn't need any compilation.

Do you perform production builds often? What is your use case for this?

@godmar
Copy link

godmar commented Dec 5, 2016

Production builds I generally don't do often, although I did find myself having to do it frequently when I debugged issues related to the PUBLIC_URL setting (in development empty string "" but a path in "production"). I also had to frequently rebuild to debug websocket related issues (since there development and production use different settings; although I understand that 0.8.0 can proxy websockets.)

For websockets, it was an issue of debugging the right combination of { path : }, nginx forwarding rules, etc. which required frequent production builds.

Having to wait 5-8s in development is however still an order of magnitude more than in other work flows. For instance, a static HTML page takes generally under 1s to update and reflect a new version of the code.

I would love to have a solution for the "multiple file" update problem. Something that tells webpack: "I'm about to update multiple files", followed by "I have updated multiple files, please rebuild"

@gaearon gaearon added this to the 1.0.0 milestone Dec 5, 2016
@gaearon
Copy link
Contributor

gaearon commented Dec 5, 2016

Tagging this so I remember to get back to it.

@godmar
Copy link

godmar commented Dec 5, 2016

PS: also remember pure development use cases where hot reloading doesn't work, for one reason or another (frequently having to run 'npm start' for development is slow too.)

@gaearon
Copy link
Contributor

gaearon commented Dec 5, 2016

Not sure what you mean by hot reloading in this case and when it doesn't work. Whenever you save a file development server should rebuild. If not it's a bug and you should file it along with any details. The "reloading" part of this triggers a reload via web sockets but it's non-essential. You can still refresh and get a fresh development build. If not it's a bug and you should file it with any details. You are not supposed to ever have to restart npm start once it's running..

@godmar
Copy link

godmar commented Dec 5, 2016

I mean that not everyone is able or willing to let their development server running all the time.

For instance, I work in an environment where the development server runs on a cloud instance (using stdout), but I work on a laptop. Whenever I change rooms, lose my network connection, I log on again and restart the development server. Every time I incur the penalty of having to wait for the entire project, usually multiple times a day.

@godmar
Copy link

godmar commented Dec 5, 2016

If you expect that npm start is long running, make it a system service.

@gaearon
Copy link
Contributor

gaearon commented Dec 6, 2016

Whenever I change rooms, lose my network connection, I log on again and restart the development server.

Can you use something like tmux to keep session alive? I think that's how people usually approach this with any other servers.

@godmar
Copy link

godmar commented Dec 6, 2016

I could, but generally don't like to have sessions hanging around on machines I'm not present on (just a personal preference).

BTW, another use case are impromptu demonstrations and teaching.

@gaearon
Copy link
Contributor

gaearon commented Dec 6, 2016

Got it. Thanks for sharing, sorry it's not great right now. One thing at a time. :-)

@themre
Copy link
Contributor

themre commented Dec 7, 2016

just came across this https://github.com/amireh/happypack if it helps anything in the future.

@gaearon
Copy link
Contributor

gaearon commented Dec 7, 2016

Unfortunately too many caveats (especially windows support).

@viankakrisna
Copy link
Contributor

How about enabling DLL plugin? I've heard people waiting 15 minutes for webpack's prod build (they are not using CRA). I think if CRA can create a sane default with this plugin, it can be the example config for those people.

The alternative are using http://fuse-box.org/. And use https://github.com/fuse-box/react-example
If you care about build speed.

In my experience, porting CRA with custom NODE_PATH to it kinda consuming, they use ~ for absolute imports.

@gaearon
Copy link
Contributor

gaearon commented Feb 24, 2017

How about enabling DLL plugin?

In my experience it's super complicated to configure, but if you can get it working well, send a PR.

@crobinson42
Copy link

@kylehotchkiss
Copy link

Hi, Just saw this ticket today along with Pinterests newly open-sourced multithreaded eslint and thought it might be relevant here:

https://medium.com/@Pinterest_Engineering/introducing-esprint-a-fast-open-source-eslint-cli-19a470cd1c7d

@alex-pex
Copy link

The alternative are using http://fuse-box.org/. And use https://github.com/fuse-box/react-example
If you care about build speed.

I know create-react-app doesn't expose Webpack to allow tool switching. Do you plan to experiment FuseBox any time soon?

@viankakrisna
Copy link
Contributor

@alex-pex I think I've put a link to a CRA fork ( / rewrite?) using fuse box somewhere in this repo. Curious how much improvements they have made right now.

@alonbardavid
Copy link

Trying to find a solution (or at least the problem) for this.
So far for anyone interested:

I've managed to easily replicate it by using the https://github.com/marmelab/admin-on-rest-demo repository - it takes me about 30 seconds to build on an dell xps 15 (Intel Core i7-6700HQ 4-core 2.6 ghz) on windows- I'm guessing it will be the same on linux/macOS.

By using V8-profiler, I've created a cpu-profile file for the webpack build phase (which takes 99% of the time of the build script). It's attached here cra-build-webpack-compile.zip .

It can be loaded into chrome's profiler to show a flame-tree and such.

I'm putting this here for posterity, but looking at the flamechart it doesn't seem to me like there is an obvious candidate that can be optimized, maybe someone else would have a different insight.

Not sure how to move further here, it seems the only reasonable way forward is to start removing plugins/loaders and see if anything causes a massive reduction in build time.

Just an aside, the build time makes it impossible for me to run CRA build script on azure's kudu build system since it consistently hits the timeout, I'm sure this happens in other CI and CD systems.

@ivosabev
Copy link
Author

It takes about 48 seconds on my Mac with 2.3 GHz Intel Core i7 + 16 GB 1600 MHz DDR3.

@p3nGu1nZz
Copy link

running your code and builds on a separate partition with SSD helps alot. Especially within windows environments. Your partition you use for your code set a very large block size. This helps speed up caching when you have lots of files. Disabling virtual memory, and shadow copies in windows helps alot.

as for the build process itself, webpack i found is slower then when i run within gulp and browserify. only lint and pretty your code when you go to stage it. Disable this for when you are doing local dev builds.

another thing i do is having a terminal open that is always building a production dist when im runing hot deployment in dev mode. i have this process hooked into certain workflow events, like after i do a new dev build or after it finished building.

Anyways these suggestion may or may not work for you. This is just stuff i found that helps speed up my commit turn around time.

GLHF;

@gaearon
Copy link
Contributor

gaearon commented Jan 8, 2018

I'm going to close this as there's not much we can do on our side. Webpack has been doing some improvements to the build time so we will pick them up as we update. If you have specific traces you want to share, please file them with webpack instead.

@gaearon gaearon closed this as completed Jan 8, 2018
@lock lock bot locked and limited conversation to collaborators Jan 20, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests