diff --git a/web/public/sw.js b/web/public/sw.js index af0539b..5d2f8cd 100644 --- a/web/public/sw.js +++ b/web/public/sw.js @@ -86,14 +86,59 @@ async function tidy() { } } -/** Keep the offline copy of the app page current, and tidy when it changes. */ +/** Keep the offline copy of the app page current, tidy when it changes, and fill in what it lists. */ async function refreshShell(res) { const html = await res.text(); const cache = await caches.open(VERSION); const prev = await cache.match(SHELL_KEY); - if (prev && (await prev.text()) === html) return; - await cache.put(SHELL_KEY, new Response(html, { headers: { "content-type": "text/html; charset=utf-8" } })); - await tidy(); + if (!prev || (await prev.text()) !== html) { + await cache.put(SHELL_KEY, new Response(html, { headers: { "content-type": "text/html; charset=utf-8" } })); + await tidy(); + } + await precache(html); +} + +/* + * Fetching the rest of the build before it is asked for. + * + * The app page lists every file of its build (see the asset-list plugin in + * vite.config.ts). Without this, the first time after a deploy that a reader + * opened the composer, settings or a viewer, it waited on the server for the + * code -- on a distant link, a visible pause. Now those files are fetched + * quietly once a page names them, a few at a time, and only those not held + * already; a load cut short is carried on at the next navigation, which calls + * this again. Language catalogs are left to be cached when used, and nothing + * is fetched ahead when the reader has asked the browser to save data. + */ +const PRECACHE_PARALLEL = 3; + +function precacheList(html) { + const m = html.match(/\n `); + }, + }, + }; +} + export default defineConfig({ base, - plugins: [react()], + plugins: [react(), assetList()], define: { __IHASMAIL_VERSION__: JSON.stringify(version) }, resolve: { alias: { "@": fileURLToPath(new URL("./src", import.meta.url)) },