From 059502f3e2fb48167137999300643dff32ed42de Mon Sep 17 00:00:00 2001 From: userquin Date: Thu, 2 Nov 2023 12:31:49 +0100 Subject: [PATCH 1/6] fix(pwa): add ignore vary to web manifests and emoji handlers --- service-worker/sw.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/service-worker/sw.ts b/service-worker/sw.ts index 1c53ff2118..7b32873df6 100644 --- a/service-worker/sw.ts +++ b/service-worker/sw.ts @@ -44,9 +44,9 @@ if (import.meta.env.PROD) { // exclude shiki: has its own cache /^\/emojis\//, // exclude sw: if the user navigates to it, fallback to index.html - /^\/sw.js$/, - // exclude webmanifest: has its own cache - /^\/manifest-(.*).webmanifest$/, + /^\/sw\.js$/, + // exclude webmanifest: has its own cache, if the user navigates to it, fallback to index.html + /^\/manifest-(.*)\.webmanifest$/, ] } @@ -54,10 +54,14 @@ if (import.meta.env.PROD) { if (import.meta.env.PROD) { // include webmanifest cache registerRoute( - ({ request, sameOrigin }) => - sameOrigin && request.destination === 'manifest', + ({ request, sameOrigin, url }) => + sameOrigin && request.destination === 'manifest' && url.pathname.startsWith('/manifest-'), new NetworkFirst({ cacheName: 'elk-webmanifest', + // responses with a Vary: Accept-Encoding header + matchOptions: { + ignoreVary: true, + }, plugins: [ new CacheableResponsePlugin({ statuses: [200] }), // we only need a few entries @@ -86,6 +90,10 @@ if (import.meta.env.PROD) { && url.pathname.startsWith('/emojis/'), new StaleWhileRevalidate({ cacheName: 'elk-emojis', + // responses with a Vary: Accept-Encoding header + matchOptions: { + ignoreVary: true, + }, plugins: [ new CacheableResponsePlugin({ statuses: [200] }), // 15 days max From 44d0e9c300ec19c271cacd667815092bfd5f7e85 Mon Sep 17 00:00:00 2001 From: userquin Date: Thu, 2 Nov 2023 12:47:37 +0100 Subject: [PATCH 2/6] chore: switch web manifest handler to stale while revalidate handler --- service-worker/sw.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/service-worker/sw.ts b/service-worker/sw.ts index 7b32873df6..94c6e54dd5 100644 --- a/service-worker/sw.ts +++ b/service-worker/sw.ts @@ -3,7 +3,7 @@ import { cleanupOutdatedCaches, createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching' import { NavigationRoute, registerRoute } from 'workbox-routing' import { CacheableResponsePlugin } from 'workbox-cacheable-response' -import { NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies' +import { StaleWhileRevalidate } from 'workbox-strategies' import { ExpirationPlugin } from 'workbox-expiration' import { onNotificationClick, onPush } from './web-push-notifications' @@ -56,7 +56,7 @@ if (import.meta.env.PROD) { registerRoute( ({ request, sameOrigin, url }) => sameOrigin && request.destination === 'manifest' && url.pathname.startsWith('/manifest-'), - new NetworkFirst({ + new StaleWhileRevalidate({ cacheName: 'elk-webmanifest', // responses with a Vary: Accept-Encoding header matchOptions: { From 40b472ce9d3d74571ab9134aff1af859661ed3bd Mon Sep 17 00:00:00 2001 From: userquin Date: Thu, 2 Nov 2023 13:34:29 +0100 Subject: [PATCH 3/6] chore: add custom plugin to log errors --- service-worker/sw.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/service-worker/sw.ts b/service-worker/sw.ts index 94c6e54dd5..e11aee9320 100644 --- a/service-worker/sw.ts +++ b/service-worker/sw.ts @@ -63,6 +63,19 @@ if (import.meta.env.PROD) { ignoreVary: true, }, plugins: [ + { + fetchDidFail: async ({ error, request }) => { + console.error('webmanifest fetchDidFail', error, request.url) + }, + handlerDidError: async ({ error, request }) => { + console.error('webmanifest handlerDidError', error, request.url) + return undefined + }, + cacheWillUpdate: async ({ request, response }) => { + console.error('webmanifest cacheWillUpdate', request.url) + return response?.status === 200 ? response : null + }, + }, new CacheableResponsePlugin({ statuses: [200] }), // we only need a few entries new ExpirationPlugin({ maxEntries: 100 }), From 0cfd6a1d33fe8c4d8ea7a8cdc0e79e2bc4c546c7 Mon Sep 17 00:00:00 2001 From: userquin Date: Thu, 2 Nov 2023 14:06:09 +0100 Subject: [PATCH 4/6] chore: remove pwa images from precaching --- config/pwa.ts | 2 +- service-worker/sw.ts | 34 +++++++++++++--------------------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/config/pwa.ts b/config/pwa.ts index 19c82b7f58..f0708d1993 100644 --- a/config/pwa.ts +++ b/config/pwa.ts @@ -14,7 +14,7 @@ export const pwa: VitePWANuxtOptions = { manifest: false, injectManifest: { globPatterns: ['**/*.{js,json,css,html,txt,svg,png,ico,webp,woff,woff2,ttf,eot,otf,wasm}'], - globIgnores: ['emojis/**', 'shiki/**', 'manifest**.webmanifest'], + globIgnores: ['emojis/**', 'shiki/**', 'manifest**.webmanifest', 'pwa-*.png', 'maskable-icon.png', 'shortcuts/**', 'screenshots/**'], manifestTransforms: [(entries) => { const manifest = entries.map((entry) => { if (entry.url.length > 1 && entry.url[0] !== '/') diff --git a/service-worker/sw.ts b/service-worker/sw.ts index e11aee9320..b5939bee4d 100644 --- a/service-worker/sw.ts +++ b/service-worker/sw.ts @@ -3,7 +3,7 @@ import { cleanupOutdatedCaches, createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching' import { NavigationRoute, registerRoute } from 'workbox-routing' import { CacheableResponsePlugin } from 'workbox-cacheable-response' -import { StaleWhileRevalidate } from 'workbox-strategies' +import { NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies' import { ExpirationPlugin } from 'workbox-expiration' import { onNotificationClick, onPush } from './web-push-notifications' @@ -33,6 +33,7 @@ if (import.meta.env.DEV) // deny api and server page calls let denylist: undefined | RegExp[] if (import.meta.env.PROD) { + const pwaIcons = /^\/(pwa-.*|maskable-icon|shortcuts\/.*|screenshots\/.*)\.(png|webp)/ denylist = [ /^\/api\//, /^\/login\//, @@ -45,37 +46,28 @@ if (import.meta.env.PROD) { /^\/emojis\//, // exclude sw: if the user navigates to it, fallback to index.html /^\/sw\.js$/, - // exclude webmanifest: has its own cache, if the user navigates to it, fallback to index.html + // exclude web manifest icons + pwaIcons, + // exclude web manifest: has its own cache, if the user navigates to it, fallback to index.html /^\/manifest-(.*)\.webmanifest$/, ] -} -// only cache pages and external assets on local build + start or in production -if (import.meta.env.PROD) { - // include webmanifest cache + // only cache pages and external assets on local build + start or in production + // include webmanifest and images cache registerRoute( ({ request, sameOrigin, url }) => - sameOrigin && request.destination === 'manifest' && url.pathname.startsWith('/manifest-'), - new StaleWhileRevalidate({ + sameOrigin && (( + request.destination === 'manifest' && url.pathname.startsWith('/manifest-') + ) || ( + request.destination === 'image' && pwaIcons.test(url.pathname) + )), + new NetworkFirst({ cacheName: 'elk-webmanifest', // responses with a Vary: Accept-Encoding header matchOptions: { ignoreVary: true, }, plugins: [ - { - fetchDidFail: async ({ error, request }) => { - console.error('webmanifest fetchDidFail', error, request.url) - }, - handlerDidError: async ({ error, request }) => { - console.error('webmanifest handlerDidError', error, request.url) - return undefined - }, - cacheWillUpdate: async ({ request, response }) => { - console.error('webmanifest cacheWillUpdate', request.url) - return response?.status === 200 ? response : null - }, - }, new CacheableResponsePlugin({ statuses: [200] }), // we only need a few entries new ExpirationPlugin({ maxEntries: 100 }), From 3f3cb16979311e4b6a9d1b124059435d1467b0e5 Mon Sep 17 00:00:00 2001 From: userquin Date: Thu, 2 Nov 2023 14:31:40 +0100 Subject: [PATCH 5/6] chore: check web manifest via precaching --- config/pwa.ts | 4 ++-- service-worker/sw.ts | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/config/pwa.ts b/config/pwa.ts index f0708d1993..abbc523c2f 100644 --- a/config/pwa.ts +++ b/config/pwa.ts @@ -13,8 +13,8 @@ export const pwa: VitePWANuxtOptions = { includeManifestIcons: false, manifest: false, injectManifest: { - globPatterns: ['**/*.{js,json,css,html,txt,svg,png,ico,webp,woff,woff2,ttf,eot,otf,wasm}'], - globIgnores: ['emojis/**', 'shiki/**', 'manifest**.webmanifest', 'pwa-*.png', 'maskable-icon.png', 'shortcuts/**', 'screenshots/**'], + globPatterns: ['**/*.{js,json,css,html,txt,svg,png,ico,webp,woff,woff2,ttf,eot,otf,wasm,webmanifest}'], + globIgnores: ['emojis/**', 'shiki/**'/* , 'manifest**.webmanifest', 'pwa-*.png', 'maskable-icon.png', 'shortcuts/**', 'screenshots/**' */], manifestTransforms: [(entries) => { const manifest = entries.map((entry) => { if (entry.url.length > 1 && entry.url[0] !== '/') diff --git a/service-worker/sw.ts b/service-worker/sw.ts index b5939bee4d..df909d6b23 100644 --- a/service-worker/sw.ts +++ b/service-worker/sw.ts @@ -3,7 +3,7 @@ import { cleanupOutdatedCaches, createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching' import { NavigationRoute, registerRoute } from 'workbox-routing' import { CacheableResponsePlugin } from 'workbox-cacheable-response' -import { NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies' +import { StaleWhileRevalidate } from 'workbox-strategies' import { ExpirationPlugin } from 'workbox-expiration' import { onNotificationClick, onPush } from './web-push-notifications' @@ -33,7 +33,7 @@ if (import.meta.env.DEV) // deny api and server page calls let denylist: undefined | RegExp[] if (import.meta.env.PROD) { - const pwaIcons = /^\/(pwa-.*|maskable-icon|shortcuts\/.*|screenshots\/.*)\.(png|webp)/ + // const pwaIcons = /^\/(pwa-.*|maskable-icon|shortcuts\/.*|screenshots\/.*)\.(png|webp)/ denylist = [ /^\/api\//, /^\/login\//, @@ -47,14 +47,14 @@ if (import.meta.env.PROD) { // exclude sw: if the user navigates to it, fallback to index.html /^\/sw\.js$/, // exclude web manifest icons - pwaIcons, + // pwaIcons, // exclude web manifest: has its own cache, if the user navigates to it, fallback to index.html - /^\/manifest-(.*)\.webmanifest$/, + /// ^\/manifest-(.*)\.webmanifest$/, ] // only cache pages and external assets on local build + start or in production // include webmanifest and images cache - registerRoute( + /* registerRoute( ({ request, sameOrigin, url }) => sameOrigin && (( request.destination === 'manifest' && url.pathname.startsWith('/manifest-') @@ -73,7 +73,7 @@ if (import.meta.env.PROD) { new ExpirationPlugin({ maxEntries: 100 }), ], }), - ) + ) */ // include shiki cache registerRoute( ({ sameOrigin, url }) => From 55e855181d0a26e409235995cb60c7bedb22ef08 Mon Sep 17 00:00:00 2001 From: userquin Date: Thu, 2 Nov 2023 15:16:37 +0100 Subject: [PATCH 6/6] chore: revert changes to use network first --- config/pwa.ts | 4 ++-- service-worker/sw.ts | 18 +++++------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/config/pwa.ts b/config/pwa.ts index abbc523c2f..19c82b7f58 100644 --- a/config/pwa.ts +++ b/config/pwa.ts @@ -13,8 +13,8 @@ export const pwa: VitePWANuxtOptions = { includeManifestIcons: false, manifest: false, injectManifest: { - globPatterns: ['**/*.{js,json,css,html,txt,svg,png,ico,webp,woff,woff2,ttf,eot,otf,wasm,webmanifest}'], - globIgnores: ['emojis/**', 'shiki/**'/* , 'manifest**.webmanifest', 'pwa-*.png', 'maskable-icon.png', 'shortcuts/**', 'screenshots/**' */], + globPatterns: ['**/*.{js,json,css,html,txt,svg,png,ico,webp,woff,woff2,ttf,eot,otf,wasm}'], + globIgnores: ['emojis/**', 'shiki/**', 'manifest**.webmanifest'], manifestTransforms: [(entries) => { const manifest = entries.map((entry) => { if (entry.url.length > 1 && entry.url[0] !== '/') diff --git a/service-worker/sw.ts b/service-worker/sw.ts index df909d6b23..61d7b5c5cd 100644 --- a/service-worker/sw.ts +++ b/service-worker/sw.ts @@ -3,7 +3,7 @@ import { cleanupOutdatedCaches, createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching' import { NavigationRoute, registerRoute } from 'workbox-routing' import { CacheableResponsePlugin } from 'workbox-cacheable-response' -import { StaleWhileRevalidate } from 'workbox-strategies' +import { NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies' import { ExpirationPlugin } from 'workbox-expiration' import { onNotificationClick, onPush } from './web-push-notifications' @@ -33,7 +33,6 @@ if (import.meta.env.DEV) // deny api and server page calls let denylist: undefined | RegExp[] if (import.meta.env.PROD) { - // const pwaIcons = /^\/(pwa-.*|maskable-icon|shortcuts\/.*|screenshots\/.*)\.(png|webp)/ denylist = [ /^\/api\//, /^\/login\//, @@ -46,21 +45,14 @@ if (import.meta.env.PROD) { /^\/emojis\//, // exclude sw: if the user navigates to it, fallback to index.html /^\/sw\.js$/, - // exclude web manifest icons - // pwaIcons, // exclude web manifest: has its own cache, if the user navigates to it, fallback to index.html - /// ^\/manifest-(.*)\.webmanifest$/, + /^\/manifest-(.*)\.webmanifest$/, ] // only cache pages and external assets on local build + start or in production // include webmanifest and images cache - /* registerRoute( - ({ request, sameOrigin, url }) => - sameOrigin && (( - request.destination === 'manifest' && url.pathname.startsWith('/manifest-') - ) || ( - request.destination === 'image' && pwaIcons.test(url.pathname) - )), + registerRoute( + ({ request, sameOrigin }) => sameOrigin && request.destination === 'manifest', new NetworkFirst({ cacheName: 'elk-webmanifest', // responses with a Vary: Accept-Encoding header @@ -73,7 +65,7 @@ if (import.meta.env.PROD) { new ExpirationPlugin({ maxEntries: 100 }), ], }), - ) */ + ) // include shiki cache registerRoute( ({ sameOrigin, url }) =>