I have been working recently on improving the caching for the new version of Meteor.
I have noticed that ChatGPT suggests caching the build-chunks with a service worker, although they are already cached by the browser. Here is the explanation:
=================================
…
Doesn’t rspack/webpack cache the assets in the browser already?

RouteLLM
Routing to Gemini 3 Flash
That is a great question. It is important to distinguish between the Browser HTTP Cache (managed by the browser and headers) and the Service Worker Cache (managed by your code).
While Rspack/Webpack/Meteor use content hashing (like main.a65b9c68...css) to make files “cacheable forever,” the Service Worker provides several critical advantages that the standard browser cache does not.
1. True Offline Capability
The standard browser HTTP cache is “passive.” If the user is offline and tries to load your SPA, the browser will simply show the “No Internet” dinosaur page. It won’t even try to look for those hashed chunks in its HTTP cache because the initial navigation request failed.
- Service Worker: Intercepts the request even when offline, serves your
index.html(shell), and then serves those hashed chunks from theCacheStorageAPI, allowing the app to boot up without a connection.
2. Bypassing “Stale” Checks
Even with long-lived cache headers, browsers sometimes perform “revalidation” (sending an If-Modified-Since request).
- Service Worker: Your
cache-firstlogic tells the browser: “Don’t even ask the network. If I have it in myBUNDLE_CACHE, use it immediately.” This makes the app load significantly faster on repeat visits.
3. Atomic Updates (The “Rotation” Logic)
This is the most important part for a Meteor/SPA developer.
- Browser Cache: If you deploy a new version, the browser might have the new
index.htmlbut still have some old chunks in its HTTP cache. If the hashes don’t match what the new app expects, the app crashes or throws a “ChunkLoadError.” - Service Worker: Your current script has “rotation” logic. When it detects a new main bundle, it can proactively clear out the old chunks. This ensures that the user’s local storage doesn’t get filled with 50 different versions of
main.jsfrom the last 10 deploys.
4. Predictable Storage
The browser’s HTTP cache is a “black box.” The browser can decide to evict files whenever it feels like it to save space.
- Service Worker: The
CacheStorageAPI is more persistent and predictable. You have explicit control over what stays and what goes.
Summary: Do you need both?
Yes.
- Rspack/Webpack provides the hashes so that the filenames are unique.
- HTTP Headers (from your CDN/Server) provide a fallback for users without Service Workers.
- Service Worker uses those hashes to provide offline support, instant loading, and clean-up logic.
Regarding your specific files:
/build-chunks/...: Definitely keep these in the Service Worker cache. They are the “meat” of your app./sockjs/...: These should never be in the Service Worker cache (and they aren’t really cached by the browser either, as they are dynamic XHR/WebSocket calls).
If you rely on the browser’s default behavior, your app will work fine while online, but it will fail the “PWA” test and won’t work offline or in “Lie-fi” (spotty connection) conditions.
=====================================
My service worker at the moment looks like the following, (next post) and it assumes you have:
- a not-connected.html as a final fallback (you first open the page when offline and you have no previous assets cached)
- PWA manifest (this is not really necessary since the pwa is cached by the browser is more than enough)
- a homescreen url for the PWA.
- a CDN (for the bundle files)
I am testing it now to see if it doesn’t over/extra catces anything but this is pretty much it. The build-chunks are stored together with the bundle files so they are being purged together with the bundle files when a new webpage version comes out.
Working on this, I used Devstral 2 (free in OpenRouter) in my code editor and Claude Sonnet 4.5 and ChatGPT-5.1 in my Abacus Chat.
This is getting lengthy but I found it really interesting how Devstral 2 totally outperforms the others in coding. I used Abacus Chat to generate the service worker based on an older service worker (Claude and ChatGPT) then I used the Code Skeptic mode in KiloCode with Devstral 2 to see what could be improved. Then I gave the result of Devstral to Claude to compare the 2 versions and Claude admitted that Devstral outperformed in almost every aspect while producing only 230 lines of code compared to 330 of Claude (these do not include the comments, only code lines).
Final report from Claude:
Final Verdict
| Criterion | Devstral(Free) | Claude Sonet 4.5 (subscription) |
|---|---|---|
| Simplicity | ||
| Readability | ||
| DRY Principle | ||
| Efficiency | ||
| Error Handling | ||
| Code Size | ||
| Maintainability |
Recommendation
Use your version (Devstral). It’s cleaner, more maintainable, and easier to debug. The efficiency gains in my version are negligible for a service worker context.