ServiceWorkers Cache everything!!!

As a performance addict, I went all in on ServiceWorkers for better or worse. I've been digging Astro lately, I keep eyes on Nuxt, VitePress and similar though. This article will actually target any vite based project including all the above ones. So ServiceWorkers have more API's and capabilities than any one man could cover, but our interest now is the CacheStorage API It's similar to storage APIs you might be familar with like localStorage etc, with one caveat; It can and will intercept http requests. This, used correctly, is super cool! So say we request a large image or file "/largeImage.png" even with the best CacheHeaders there can be a delay in the response, not so with the CacheStorage API. We will intercept the request and respond with a locally browser stored version and depending on our ServiceWorker strategy possibly check for a fresher Network (external) version. This also immediately enables Offline support. Because we intercept these requests, we do not need to be online at all. Neat! So using VitePWA you might have a config like AstroPWA({ srcDir: "src", includeManifestIcons: false, includeAssets: [ "**/*", ], pwaAssets: { config: true, }, maxEntries: 500, workbox: { globPatterns: ['**/*.{js,html, png, jpg, jpeg, svg, webp, avif, js, woff, woff2, txt, ttf }'], runtimeCaching: [ { urlPattern: /\.(?:png|jpg|jpeg|svg|html|js|avif|webp|woff2|woff|webp|js|txt|ttf)$/i, handler: "CacheFirst", options: { cacheName: 'main', expiration: { maxAgeSeconds: 60 * 60 * 24 * 365, maxEntries: 500, }, }, }, ], cleanupOutdatedCaches: true, maximumFileSizeToCacheInBytes: 5 * 1024 * 1024 * 5 * 99, }, devOptions: { type: "module", enabled: true, navigateFallbackAllowlist: [/^\//], } }), This is probably not optimal at all, in-fact it definitely isn't, but I'll explain it. So the top-level includeAssets is AFAIK a pre-cache of resources, it might be pointing at your /public folder framework depending. It's better to actually specify resources then my wild cache it all **/*. Why, because the first page load will be slow, and cache things not even related to the page the user is viewing. (As a crazy person, I use this, and no amount of therapy will change me.) Now runtimeCaching this is pretty cool, it's basically grabbing resources as they are requested "at runtime"; basically anything external and not in your "/public" folder. This is probably one should lean on more then the includedAssets. This has some powerful options like strategy, handler: "CacheFirst" is probably the best IMO. Find many more here. Ok let's move on to a side-note more about PWA capabilities generating PWA Assets, so basically the webmanifest and appropriate icons. This makes your App/Website installable to a Desktop/Android/iOS. So you might include PWA-assets-generator pnpm add -D @vite-pwa/assets-generator You can now use it like pwa-assets-generator --preset minimal-2023 public/logo.svg or add as an npm script like { "scripts": { "generate-pwa-assets": "pwa-assets-generator --preset minimal-2023 public/logo.svg" } } or many framework integrations will have an option like: AstroPWA({ pwaAssets: { config: true, } }) nuxt would be similarly: export default defineNuxtConfig({ modules: ['@vite-pwa/nuxt'], pwa: { pwaAssets: { config: true, } } }) Which will read a config file and automatically generate on build. Let me know any questions or thought! or critiques! an example of all responses from my blog:

May 9, 2025 - 21:44
 0
ServiceWorkers Cache everything!!!

As a performance addict, I went all in on ServiceWorkers for better or worse.

I've been digging Astro lately, I keep eyes on Nuxt, VitePress and similar though.

This article will actually target any vite based project including all the above ones.

So ServiceWorkers have more API's and capabilities than any one man could cover, but our interest now is the CacheStorage API It's similar to storage APIs you might be familar with like localStorage etc, with one caveat; It can and will intercept http requests.

This, used correctly, is super cool! So say we request a large image or file "/largeImage.png" even with the best CacheHeaders there can be a delay in the response, not so with the CacheStorage API.

We will intercept the request and respond with a locally browser stored version and depending on our ServiceWorker strategy possibly check for a fresher Network (external) version. This also immediately enables Offline support. Because we intercept these requests, we do not need to be online at all.

Neat!

So using VitePWA you might have a config like

  AstroPWA({
      srcDir: "src",
      includeManifestIcons: false,
      includeAssets: [
        "**/*",
    ],

      pwaAssets: {
        config: true,
      },
      maxEntries: 500,
      workbox: {
        globPatterns: ['**/*.{js,html, png, jpg, jpeg, svg, webp, avif, js, woff, woff2, txt, ttf }'],
        runtimeCaching: [
          {

            urlPattern: /\.(?:png|jpg|jpeg|svg|html|js|avif|webp|woff2|woff|webp|js|txt|ttf)$/i,
            handler: "CacheFirst",
            options: {
              cacheName: 'main',
              expiration: {
                maxAgeSeconds: 60 * 60 * 24 * 365,
                maxEntries: 500,
              },
            },
          },
        ],

        cleanupOutdatedCaches: true,
        maximumFileSizeToCacheInBytes: 5 * 1024 * 1024 * 5 * 99,

      },
      devOptions: {
        type: "module",
        enabled: true,
        navigateFallbackAllowlist: [/^\//],
      }
    }),

This is probably not optimal at all, in-fact it definitely isn't, but I'll explain it. So the top-level includeAssets is AFAIK a pre-cache of resources, it might be pointing at your /public folder framework depending. It's better to actually specify resources then my wild cache it all **/*. Why, because the first page load will be slow, and cache things not even related to the page the user is viewing. (As a crazy person, I use this, and no amount of therapy will change me.)

Now runtimeCaching this is pretty cool, it's basically grabbing resources as they are requested "at runtime"; basically anything external and not in your "/public" folder. This is probably one should lean on more then the includedAssets. This has some powerful options like strategy, handler: "CacheFirst" is probably the best IMO. Find many more here.

Ok let's move on to a side-note more about PWA capabilities generating PWA Assets, so basically the webmanifest and appropriate icons. This makes your App/Website installable to a Desktop/Android/iOS.

So you might include PWA-assets-generator pnpm add -D @vite-pwa/assets-generator

You can now use it like
pwa-assets-generator --preset minimal-2023 public/logo.svg
or add as an npm script like

{
  "scripts": {
    "generate-pwa-assets": "pwa-assets-generator --preset minimal-2023 public/logo.svg"
  }
}

or many framework integrations will have an option like:

 AstroPWA({
 pwaAssets: {
        config: true,
      }
})

nuxt would be similarly:

export default defineNuxtConfig({
  modules: ['@vite-pwa/nuxt'],
  pwa: {
    pwaAssets: {
        config: true,
      }
  }
})

Which will read a config file and automatically generate on build.

Let me know any questions or thought! or critiques!

an example of all responses from my blog:
Image description