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 webpack dll plugin for faster rebuilds #1651

Closed
wants to merge 64 commits into from

Conversation

viankakrisna
Copy link
Contributor

@viankakrisna viankakrisna commented Feb 26, 2017

POC for #913
currently, it uses node_modules/.cache/dll for storing cached vendor builds and add src/index.dll.js entry point for requiring dependencies. It also hashes the filenames so it is safe to use in production.

Todos:

  • Cleaner index.html. Reference the vendor on build times
  • Show vendor build file size
  • Enhance eject experience
  • Cleaner log message <-- need feedback
  • Update the docs
  • Figure out a better place to store the vendor build. Using public/vendor not quite intuitive
  • Only use this feature if user have a index.dll.js in their ./src folder

@tbillington
Copy link

@viankakrisna Just curious, what kind of speedup do you see using this method?

@viankakrisna
Copy link
Contributor Author

@tbillington here's the numbers, i've not yet done repeated test, but it should gave you the gist:

465 Files in src

dependencies:
"hellojs": "^1.14.0",
"isomorphic-fetch": "^2.2.1",
"konva": "^1.3.0",
"lodash": "^4.16.3",
"react": "^15.3.2",
"react-bootstrap": "^0.30.3",
"react-color": "^2.11.1",
"react-datepicker": "^0.39.0",
"react-dom": "^15.3.2",
"react-helmet": "^3.2.3",
"react-konva": "^1.1.1",
"react-number-format": "^0.1.3",
"react-redux": "^4.4.5",
"react-router": "^2.8.1",
"react-router-bootstrap": "^0.23.1",
"react-router-form": "^3.0.0",
"react-router-redux": "^4.0.6",
"react-router-scroll": "^0.3.3",
"react-scrollbar": "^0.4.2",
"react-share": "^1.10.0",
"react-slick": "^0.14.5",
"react-sticky": "^5.0.5",
"react-tagsinput": "^3.13.6",
"redux": "^3.6.0",
"redux-form": "^6.4.3",
"redux-thunk": "^2.1.0",
"smoothscroll-polyfill": "^0.3.4",
"styled-components": "^1.4.3"

0.9.2
yarn run build - cold - 148.49s
yarn run build - warm - 119.53s

0.9.2 + DLL enabled
yarn run build - cold - 121.25s
yarn run build - warm - 55.67s

Will update more when i have done repeated test. In general, it improves the warm build significantly.

@viankakrisna
Copy link
Contributor Author

viankakrisna commented Feb 27, 2017

Also, the build size is not optimized, it's only reading from package json. So if you have lodash there, you will get full lodash in the build. There are no optimization except minifying happening in here T.T. I haven't found other ways to do it though, happy to get input from all the webpack master 😄

UPDATE: it uses a vendor entry point right now so we don't end up with full lodash on dll when it is listed as dependencies

@ekosz
Copy link

ekosz commented Feb 28, 2017

Should this be used for the production build as well? Normally I've seen DLL in dev and CommonChunk plugin for the production build. Example here: https://github.com/react-boilerplate/react-boilerplate

@gaearon
Copy link
Contributor

gaearon commented Feb 28, 2017

This is an interesting direction, but seems very complex to me. I don’t think this is something we’d want to leave users with after they eject.

@viankakrisna
Copy link
Contributor Author

viankakrisna commented Feb 28, 2017

@gaearon well, this is just a proof of concept, i don't mind if it doesn't end up released. Just curious exploring what the sane defaults are 😄

@ekosz from this https://robertknight.github.io/posts/webpack-dll-plugins/

The advantage is that you only need one Webpack configuration. The disadvantage for large projects is that the 'commons' chunk will be recompiled every time you run Webpack.

My focus here is the build time. It's frustrating to wait for it to finish in large project. Especially if there's a critical bugfix in production.

I'm thinking that this feature could be an opt in, for users that have grown their project and wanted to have fast iteration. From my personal experience, a lot of developers turned off from using module bundlers because they are concerned about the build times and configuration.

I think create react app already did a good job in configuring the sane defaults for newcomers, and if we can optimize it to be blazing fast when the user scale, it would make the tool more appealing.

And of course, this is just my opinion. Open to suggestion and feedbacks :)

@viankakrisna viankakrisna changed the title use webpack dll plugin for faster rebuilds [WIP] use webpack dll plugin for faster rebuilds Mar 10, 2017
@Timer Timer mentioned this pull request May 5, 2017
32 tasks
@viankakrisna
Copy link
Contributor Author

viankakrisna commented May 22, 2017

renamed entry point to index.dll.js to be explicit.

@vikrantpogula
Copy link

vikrantpogula commented May 31, 2017

@viankakrisna Great PR ! Been following from a few days. Love that this is opt-in.

I've always been trying to hack together something similar to improve build times, every time that I've been making SPAs from a while now (gulp, webpack etc), and have always created a separate DLL/file for dependencies which don't change between builds.

A caveat of doing is is always almost larger bundle sizes shipped, and losing benefits of tree-shaking and modules. For example, (most common use case here) one would be tempted to import even a modular library like lodash in index.dll.js but use only 1 or 2 methods from the library. Direct imports would tree-shake and not import the whole module. But using a DLL (without proper consideration and imports) would bloat up the total amount of code shipped.

I think it should always be documented the pros and cons of using DLLs / vendor bundles. Would love to know your thoughts.

cc @gaearon

@viankakrisna
Copy link
Contributor Author

@vikrantpogula Thanks! Yeah, we need a proper docs for this feature, especially for the un-tree-shakable dll. Wanna help? 😃

@gaearon After reading https://medium.com/making-internets/webpack-configuration-done-right-86c325a6927f , I've been thinking maybe we should have a internal hook for composing webpack config,
right now AFAIK we have 3 three separate PR working on adding something to webpack config, 2 of them is optional (dll and commonsChunk) and one is css module. And for the merged ones, SWPrecache is an optional feature but we still have the webpack plugins installed, even when the user is not using it. I think we should go with something like https://github.com/viankakrisna/create-react-app/blob/f9434812a9c2d06166f71b816784dd109ff15f1a/packages/react-scripts/scripts/start.js#L55-L60 for easier enabling and disabling feature (even after ejected) and to keep webpack config minimal. Thoughts?

@vikrantpogula
Copy link

@viankakrisna sure will work on it. upon further research it looks like tree-shaking is still broken (not stable ?) in webpack 2. ref: webpack/webpack#2867

Ill try this PR in a sample repository and get back how it goes, but I can only in the weekend or next week !

@viankakrisna
Copy link
Contributor Author

@vikrantpogula yeah, I mean dead code elimination etc which is impossible because it's a different build altogether. Please do! Appreciate the help. :)

@viankakrisna
Copy link
Contributor Author

closing this for #2710

@lock lock bot locked and limited conversation to collaborators Jan 21, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants