(Publicly asking/answering on behalf of someone.)
I'm using Workbox to generate a service worker that precaches resources for my progressive web app.
Am I wrong to be reluctant to precache ~20mb of minified JavaScript? It's huge, obviously. 20mb seems way too much. My plan was to just precache the essential stuff, and use runtime caching for the rest.
In other words, what are some general heuristics for determining what should and shouldn't be included in the precache payload?
There's a lot of nuance here, and the right answer comes down to a mix of understanding your users and understanding your resources.
User Considerations
One of the main considerations is whether forcing a ~20mb download of data is respectful of your target user base.
If you're developing an in-house PWA for a corporate client, then you might be fairly sure that the majority of users will be on a fast connection, and not paying by the megabyte for their data plan.
If you're developing for a market that includes folks who are on slower, metered connections, avoiding automatic precaching of large payloads is a good idea. You could either decrease your precache payload size, or alternatively, delay service worker registration until after they've engaged with your PWA a bit—at that point, if they're using your site, they're more likely to derive value from things being cached and it won't feel like a "drive-by data dump".
Understanding your resources
In the original question, the ~20mb were said to be JavaScript resources, and my assumption is that they are all assets that are lazy-loaded for various views in your web app.
Prefer many smaller individual assets vs. fewer bundled larger assets
Beyond thinking about the initial cost of precaching, you should be concerned with the ongoing cost of expiring and refetching entries that were previously precached as you make changes to your site over time.
If you have 20 individual bundles precached, and each of those are ~1mb, then making a change to a single file in one of the bundles will cause ~1mb of data to be transferred as part of the follow-on update. If you have 2 individual bundles and each are ~10mb, then changing that same file will cause ~10mb of data to be transferred. The cost of keeping your precached assets up to date can, over time, easily outweigh the initial cost of precaching, so try to keep that in mind when bundling.
Only precache assets for views that are likely to be used
This follows from the previous point—try to avoid precaching lazy-loaded assets that are only going to be requested by a low percentage of your users. Even if the assets themselves are small, there's a cost of keeping them up to date that those users pay each time you make a change to any of the files that make up those bundles. You could easily introduce a situation where, over time, a user downloads and re-downloads JS that will never end up being executed.
Don't precache images (usually)
(This assumes that you're considering whether to precache images.)
Images, unless they're used as part of your user interface on many pages, are not great candidates for precaching. They obviously tend to be large, and if they fail to load because you're offline and they're not in the cache, then hopefully you have alternative text in your HTML markup to display in their place.
Using a runtime caching strategy, along with a cache expiration policy, is usually the best advice for images.