Create-react-app: Why does the service-worker pre-cache all my chunks when doing code-splitting?

Created on 29 Jan 2018  路  4Comments  路  Source: facebook/create-react-app

Is this a bug report?

No

Thanks to react-loadable, my react-router only loads my chunks when a user hits a specific route in my create-react-app project.
On localhost, I can see that each route will load the right chunk via the network tab in Chrome DevTools. However, when being deployed on prod (with https), the service-worker will preload all the chunks on landing page (type: fetch | initiator: service-worker.js | size: x KB). Then when the user hits a route, I can see that the chunk is being served by the SW (type: script | size: (from ServiceWorker)).
I've followed the tutorial provided by the create-react-app documentation. I am not ejected and I haven't touch to registerServiceWorker.js.
Am I supposed to unregister the SW? Because at first I've imagined this behavior:

  • The app would load my appshell;
  • The user hits a route and download the related chunk;
  • The SW caches the chunk;
  • Then if the user comes back, no need to re-download the chunk.
question > PWA

Most helpful comment

What you're seeing is expected with the current implementation. (You won't see this with newly created projects in the upcoming major release of c-r-a, as service worker registration will be disabled by default.)

During the service worker's installation, all of the assets from your webpack compilation will be precached, including assets that are not used to display the initial view.

Service worker registration happens after a window.onload event has fired, so (ideally) the precaching is not going to cause bandwidth contention with any resources that are part of the initial critical rendering pipeline.

The upside is that the next time you visit your web app, when you navigate any view, that view's rendering won't be blocked on the network, since the JS can will read from the service worker's cache rather than the network.

The downside is that if you have some views that are very unlikely to be navigated to, and/or require large JS payloads in order to render, the JS for those views will be downloaded as part of the service worker's precaching, and you could consider those "wasted" bytes.

The underlying service worker library does have the ability to exclude a certain subset of the webpack asset pipeline from precaching, and potentially configure a cache-as-you-go strategy for those assets. Unfortunately, you need to make changes to the webpack configuration in order to achieve that behavior, and that's not something you can easily do with c-r-a without ejecting first. Given the zero-config philosophy, caching everything from the webpack asset pipeline was the most useful default.

All 4 comments

cc @jeffposnick

I confirm that the same code but without the service worker will download the chunks as expected.
https://csb-w7pnvkp057-fdyfurtvre.now.sh

What you're seeing is expected with the current implementation. (You won't see this with newly created projects in the upcoming major release of c-r-a, as service worker registration will be disabled by default.)

During the service worker's installation, all of the assets from your webpack compilation will be precached, including assets that are not used to display the initial view.

Service worker registration happens after a window.onload event has fired, so (ideally) the precaching is not going to cause bandwidth contention with any resources that are part of the initial critical rendering pipeline.

The upside is that the next time you visit your web app, when you navigate any view, that view's rendering won't be blocked on the network, since the JS can will read from the service worker's cache rather than the network.

The downside is that if you have some views that are very unlikely to be navigated to, and/or require large JS payloads in order to render, the JS for those views will be downloaded as part of the service worker's precaching, and you could consider those "wasted" bytes.

The underlying service worker library does have the ability to exclude a certain subset of the webpack asset pipeline from precaching, and potentially configure a cache-as-you-go strategy for those assets. Unfortunately, you need to make changes to the webpack configuration in order to achieve that behavior, and that's not something you can easily do with c-r-a without ejecting first. Given the zero-config philosophy, caching everything from the webpack asset pipeline was the most useful default.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dualcnhq picture dualcnhq  路  3Comments

xgqfrms-GitHub picture xgqfrms-GitHub  路  3Comments

Aranir picture Aranir  路  3Comments

oltsa picture oltsa  路  3Comments

alleroux picture alleroux  路  3Comments