Plate 25
vite-plugin-pwa: +1.25s Build Overhead
Vite 8.3.2 plain vs Vite 8.3.2 + vite-plugin-pwa 2.0.0 generateSW on a 40-card vanilla app (minify off). Warm medians (7 rounds, cache cleared): plain 202 ms vs PWA 1,452 ms (+1,250 ms). Dist 4,426 B / 5 files → 21,142 B / 8 files (sw.js 1,347 B, workbox 15,026 B, manifest 293 B). Fixture /workspace/bench-vite-pwa/.
Aditya Challa4 min read
I timed seven clean Vite 8.3 builds of a 40-card static app on this box: plain median 202 ms, with vite-plugin-pwa 1,452 ms — about +1.25 s (+619%) for generateSW, a webmanifest, and Workbox.
Short answer: worth it if you need installability or offline caching; skip it if you only want a fast static deploy and no service worker. No affiliate links in this post.
What I tested
- Machine: 8 vCPU Intel Xeon / 15 GB RAM shared Linux cloud box, tested 6 Oct 2026 about 00:18–00:19 IST.
- Versions: Vite 8.3.2; vite-plugin-pwa 2.0.0; Node 22.20.0.
- Fixture: /workspace/bench-vite-pwa/. Vanilla HTML entry, 40 inline cards, CSS module-free. Two configs: vite.config.ts (no PWA) and vite.config.pwa.ts (VitePWA registerType autoUpdate, injectRegister false, generateSW via Workbox, icons in public/).
- Timing: wall clock around
vite buildwith local binary; dist + node_modules/.vite cleared each run; 1 warm-up each config, then 7 interleaved timed rounds. minify and cssMinify off so the gap is plugin work, not terser. - Findings: plain median 202 ms (min 194 / max 240). PWA median 1,452 ms (min 1,371 / max 1,670). Delta +1,250 ms. Dist file count 5 → 8; bytes 4,426 → 21,142. Artifacts: manifest.webmanifest 293 B, sw.js 1,347 B, workbox-*.js 15,026 B.
- One surprise: Workbox alone was ~15 KB on this tiny app — larger than the whole plain dist — while the build tax stayed over a second every warm round.
- Not tested: injectManifest, offline navigation routes, push notifications, precache of large asset sets, Safari install quirks, Windows or macOS, SSR frameworks.
How much did the PWA plugin add?
| Build | Median wall | Min / Max | Dist files / bytes |
|---|---|---|---|
| Vite 8.3 plain | 202 ms | 194 / 240 | 5 / 4,426 B |
| Vite 8.3 + vite-plugin-pwa | 1,452 ms | 1,371 / 1,670 | 8 / 21,142 B |
Same source, same box, caches cleared. The plugin ran Workbox generateSW after the Rollup emit; that post-pass dominated the stopwatch on this small app.
For Vite baseline context on this site, see Vite vs Parcel and Vite 8.3.2 renderBuiltUrl notes. If you already run type-checking in Vite, compare vite-plugin-checker vs tsc.
Is the overhead only Workbox size?
No. Bytes matter for clients; wall clock matters for CI. Here the client picked up ~16.5 KB of SW+Workbox+manifest on top of icons, and CI paid about 1.25 s per clean build. On a huge asset graph the precache step can grow further; I did not scale the fixture.
Vite Plus 1.0 toolchain notes cover a different "one toolchain" bet. This post is narrower: do you want vite-plugin-pwa's generateSW on an ordinary Vite app.
Should you enable vite-plugin-pwa?
| Situation | My pick |
|---|---|
| Marketing site, no offline need | Skip the plugin |
| Installable app / field tool with flaky network | Enable generateSW |
| CI already slow and deploys are static-only | Skip until product asks for a SW |
| Need custom SW logic (push, complex routing) | Consider injectManifest later; not tested here |
| Watching transfer size budgets | Pair with size-limit vs bundlesize |
| CSS tooling decision in the same stack | See Lightning CSS vs PostCSS |
Bottom line: on a 40-card Vite 8.3 app, vite-plugin-pwa moved median build from 202 ms to 1,452 ms and added sw.js plus ~15 KB Workbox. Who should not add it: teams that do not need a service worker and already guard CI minutes.
How this was made: I scaffolded a vanilla Vite app on the ShopperCove box, built it seven times with and without vite-plugin-pwa after warm-ups and cache clears, recorded JSON medians and dist artifacts; the write-up was drafted with AI help and checked against that output.
Sources
- https://vite-pwa-org.netlify.app/
- https://github.com/vite-pwa/vite-plugin-pwa
- https://www.npmjs.com/package/vite-plugin-pwa
- https://vite.dev/guide/
- https://developer.chrome.com/docs/workbox/
Related
- https://www.shoppercove.com/blog/vite-vs-parcel
- https://www.shoppercove.com/blog/vite-8-3-2-renderbuilturl-bundled-dev-sourcemaps-october-2026
- https://www.shoppercove.com/blog/vite-plugin-checker-vs-tsc
- https://www.shoppercove.com/blog/vite-plus-1-0-unified-toolchain-october-2026
- https://www.shoppercove.com/blog/size-limit-vs-bundlesize
- https://www.shoppercove.com/blog/lightningcss-vs-postcss
- https://www.shoppercove.com/blog/rolldown-vs-rollup
- https://www.shoppercove.com/blog/swc-vs-esbuild-babel
Lab evidence
What I found running this
Hands-on on ShopperCove box 6 Oct 2026 ~00:18–00:19 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 22.20.0). Vite 8.3.2 vs Vite 8.3.2 + vite-plugin-pwa 2.0.0 (generateSW, autoUpdate, injectRegister false). Fixture /workspace/bench-vite-pwa/: 40-card vanilla HTML/CSS; minify off; dist + .vite cleared each run; 1 warm-up + 7 interleaved rounds. Medians plain 202 ms (194–240) vs PWA 1,452 ms (1,371–1,670); delta +1,250 ms. Dist 5/4,426 B → 8/21,142 B; manifest 293 B, sw.js 1,347 B, workbox 15,026 B. Raw: /workspace/bench-vite-pwa/res-vite-pwa.json. Not tested: injectManifest, push, large precache, Safari install, SSR, Windows/macOS. No affiliate.
Related links
Plate 88
Sharp vs Jimp: 112ms vs 366ms Resize
sharp 0.35.5 vs Jimp 1.6.1 on one 1920×1080 JPEG → width 800 JPEG q80. Warm medians (7 rounds after 1 warm-up): sharp 112 ms / 142,435 B vs Jimp 366 ms / 269,590 B (~3.3×). Fixture /workspace/bench-sharp-jimp/.
5 Oct 2026
Plate 93
UnoCSS vs Tailwind: 10.5KB vs 18.5KB CSS
UnoCSS 66.5.2 (presetWind3) vs Tailwind CSS 4.1.13 (@tailwindcss/vite) on Vite 7.3.6: 80 HTML cards, same utility set, minify off. CSS 10,454 B (118 selectors) vs 18,473 B (119). Warm vite build medians (7 rounds, cache cleared): Uno 749 ms vs Tailwind 416 ms. Fixture /workspace/bench-unocss-tw/.
5 Oct 2026
Plate 30
unplugin-auto-import: 360 Import Lines vs +267ms
unplugin-auto-import 20.3.0 + unplugin-vue-components 29.2.0 on Vue 3.5.43 / Vite 7.3.6: 40 components, 40 utils, 20 composables. Import lines 382 → 22 (−360). Warm production build medians (minify off, 7 rounds): manual 940 ms vs auto 1,207 ms (+267 ms); both 105 modules; JS 209.03 → 210.88 kB.
5 Oct 2026