Fetch the rest of a new build in the background #394

Closed
opened 2026-09-16 20:25:33 +00:00 by jcoffey-dev · 0 comments
Owner

Part of the high-latency work.

The problem.

  • The app page names only the files it loads at start. The composer, settings, admin, calendar, contacts, files and viewers were each fetched the first time they were opened, and after every deploy that first open waited on the server.
  • The worker's cleanup also dropped any file the page didn't name, so those chunks were re-downloaded after every deploy regardless.

The change.

  • Build: a small Vite plugin writes every file of the build into index.html as <script type="application/json" id="ihasmail-assets">. The list is split into precache and onDemand, where onDemand holds the 8 non-English language catalogs.
    • An inert data block isn't executed, so script-src 'self' is unaffected.
    • Prefetch links weren't used, because the browser would fetch them on every load.
    • The HTML is no-cache, so the list is never served stale by a CDN.
  • Service worker:
    • The existing cleanup already keeps every /assets/ path the page names, so listed chunks now survive.
    • On each navigation, refreshShell fetches any listed precache file it doesn't hold, three at a time, and caches only successful responses.
    • A load that's cut short resumes on the next navigation.
    • Nothing is fetched ahead when navigator.connection.saveData is set.
    • Language catalogs are still cached when first used.

Measured in Chrome against a local build:

  • One navigation after the update cached all 47 listed files.
  • The previous build's 20 cached files were cleared.
  • No language catalog was fetched.
  • Opening Settings then came from the worker in 2 ms, with 0 bytes transferred.
  • Cost per deploy: about 300–400 KB brotli, fetched in the background.

Tests. Web: 1,363 pass; typecheck is clean. sw.js is copied verbatim and has no unit tests, so it was verified in the browser as above.

No new UI strings.

Merged 2026-09-16 as coffey-labs/ihasmail@4c67460450

Rebuilt from: git history, session transcript.

Part of the high-latency work. **The problem.** - The app page names only the files it loads at start. The composer, settings, admin, calendar, contacts, files and viewers were each fetched the first time they were opened, and after every deploy that first open waited on the server. - The worker's cleanup also dropped any file the page didn't name, so those chunks were re-downloaded after every deploy regardless. **The change.** - **Build:** a small Vite plugin writes every file of the build into `index.html` as `<script type="application/json" id="ihasmail-assets">`. The list is split into `precache` and `onDemand`, where `onDemand` holds the 8 non-English language catalogs. - An inert data block isn't executed, so `script-src 'self'` is unaffected. - Prefetch links weren't used, because the browser would fetch them on every load. - The HTML is `no-cache`, so the list is never served stale by a CDN. - **Service worker:** - The existing cleanup already keeps every `/assets/` path the page names, so listed chunks now survive. - On each navigation, `refreshShell` fetches any listed `precache` file it doesn't hold, three at a time, and caches only successful responses. - A load that's cut short resumes on the next navigation. - Nothing is fetched ahead when `navigator.connection.saveData` is set. - Language catalogs are still cached when first used. **Measured** in Chrome against a local build: - One navigation after the update cached all 47 listed files. - The previous build's 20 cached files were cleared. - No language catalog was fetched. - Opening Settings then came from the worker in 2 ms, with 0 bytes transferred. - Cost per deploy: about 300–400 KB brotli, fetched in the background. **Tests.** Web: 1,363 pass; typecheck is clean. `sw.js` is copied verbatim and has no unit tests, so it was verified in the browser as above. No new UI strings. **Merged** 2026-09-16 as coffey-labs/ihasmail@4c674604509f <sub>Rebuilt from: git history, session transcript.</sub>
This repo is archived. You cannot comment on issues.