Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • C create-react-app
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 1,547
    • Issues 1,547
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 417
    • Merge requests 417
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Meta
  • create-react-app
  • Merge requests
  • !227

Split React into a separate chunk and fix long-term caching

  • Review changes

  • Download
  • Email patches
  • Plain diff
Closed Administrator requested to merge manifest into master Jul 26, 2016
  • Overview 17
  • Commits 2
  • Pipelines 0
  • Changes 3

Created by: gaearon

Curiously, out of the box Webpack doesn’t handle long term caching very well. Granted, it’s not a very simple problem for a bunch of reasons:

  • Both JS and CSS are first-class modules and can be put in chunks
  • Webpack has code splitting API so chunks need to know about each other
  • ... but if they know each other’s filenames, their hashes depend on one another!

This problem is described here, and if you have nothing better to do with your evening, you can read through this issue: https://github.com/webpack/webpack/issues/1315. (I did.)

This PR makes a bunch of improvements to longer term caching of the apps we generate. I used different solutions linked from https://github.com/webpack/webpack/issues/1315 as inspiration. The result config is a little bit intimidating but I believe it provides a sufficiently better experience for production apps. This solves a few problems:

  • Changes to CSS shouldn’t invalidate JS.
  • Updating React shouldn’t invalidate app code.
  • Changes to async bundles shouldn’t invalidate the root bundle.

Test Plan

I will provide a comparison of how often we bust caches below and after this change. I got it by repeating the same operations over time and comparing requests in Network tab.

Before

main.455a59df.js
main.9a0fe4f1.css
logo.84287d09.svg

### change CSS

main.6f795e0f.js  [!] bad: updating CSS shouldn't bump JS
main.d57c128d.css [*]
logo.84287d09.svg

### change CSS again

main.f0bce2a4.js  [!] bad: updating CSS shouldn't bump JS
main.d42a29cb.css [*]
logo.84287d09.svg

### change JS

main.8f645d9d.js  [*]
main.d42a29cb.css
logo.84287d09.svg

### change CSS back

main.8301d559.js  [!] bad: updating CSS shouldn't bump JS
main.9a0fe4f1.css [*]
logo.84287d09.svg

### add async JS bundle

main.a34625e7.js    [*]
main.65027555.css   [*]
1.67fca831.chunk.js [*]
logo.84287d09.svg

### change async JS bundle

main.3a030413.js    [!] bad: changing async shouldn't bump root
main.65027555.css
1.df221dec.chunk.js [*]
logo.84287d09.svg

### change JS

main.ce52003f.js [*]
main.65027555.css
1.df221dec.chunk.js
logo.84287d09.svg

### update React

main.733b24be.js    [!] bad: updating React shouldn't bump root
main.65027555.css
1.a9207a9f.chunk.js [!] bad: updating React shouldn't bump split
logo.84287d09.svg

After

vendor.ad62e36d.js
main.a83bc981.js
main.9a0fe4f1.css
logo.84287d09.svg

### change CSS

vendor.ad62e36d.js
main.a83bc981.js
main.d57c128d.css [*]
logo.84287d09.svg

### change CSS again

vendor.ad62e36d.js 
main.a83bc981.js  
main.d42a29cb.css [*]
logo.84287d09.svg

### change JS

vendor.ad62e36d.js
main.6a8181e8.js   [*]
main.d42a29cb.css
logo.84287d09.svg

### change CSS back

vendor.ad62e36d.js
main.6a8181e8.js 
main.9a0fe4f1.css  [*]
logo.84287d09.svg

### add async JS bundle

vendor.ad62e36d.js 
main.8945b1c6.js    [*]
main.65027555.css   [*]
0.dc08343c.chunk.js [*]
logo.84287d09.svg

### change async JS bundle

vendor.ad62e36d.js
main.8945b1c6.js
main.65027555.css
0.f9c57019.chunk.js [*]
logo.84287d09.svg

### change JS

vendor.ad62e36d.js
main.a29f4c4f.js    [*]
main.65027555.css
0.f9c57019.chunk.js
logo.84287d09.svg

### update React

vendor.425b0082.js  [*]
main.a29f4c4f.js
main.65027555.css
0.f9c57019.chunk.js
logo.84287d09.svg

Revert Plan

I don’t see why we would have issues with this especially considering that user can’t configure anything (and thus potentially break something). Worst case, we remove these plugins / options because they are strictly additive and won’t be a breaking change.

This complicates the post-eject configuration but I think it’s not a big issue especially considering this feature is something people actively want when configuring webpack. There is a reason https://github.com/webpack/webpack/issues/1315 has 120 comments.

Future Plans

We can add more stuff to vendor bundle in a smart way. For example we could whitelist certain projects that don’t change too often explicitly, of we could apply some heuristic (e.g. most people would likely want any polyfills and stuff like React Router to end up there). This can be discussed separately.

Alternatives

We could point people to React CDN builds. Unfortunately this doesn’t solve issues with CSS invalidating JS. It also doesn’t currently play well with npm addons. And it won’t fix the issues with code splitting (if people ever get to that, which they do in real apps). So I feel like, until Webpack provides something better out of the box, this is a sensible solution.

Assignee
Assign to
Reviewers
Request review from
Time tracking
Source branch: manifest