Closed pavlexander closed 2 years ago
@pavlexander you can exclude secured pages from the sw precache manifest (will not work on offline, but also you cannot login into the app) or you can protect the data on that pages (loading data before routing to the page and/or prevent that transition: you will need to protect on the server, no matter if the page can be fetched or not).
You can also build a custom sw with custom routing, but yo will need to check the workbox docs.
I have all my apps with all pages with public access, anyone can request secured pages: I use an interceptor on the client checking the login state to prevent routing (redirect to home) and on server checking also the user is logged when requesting secured data.
@userquin I should have probably mentioned that this is not done for security reasons. There is no such thing as security for the frontend :D The backend server is protected against the write attempts of unauthenticated users just fine.
The reason I was thinking about is the SEO optimization. There are 21 pages on production environment that are secured by authentication. Total size of these files are 512kb (for JS) at this moment (+15kb CSS). So, in theory, I could save around 0.5mb of data for every single page viewing requests for every user. As well as for google bot and other crawlers, hence resulting in higher site rankings.
You can also build a custom sw with custom routing, but yo will need to check the workbox docs.
For this to happen - do I have to basically ditch the vite-plugin-pwa
plugin? I mean if I switch to barebone workbox solution then the plugin is not required, right? I am wondering if there are additional quality of life improvements done in this plugin, that I should be concerned about, before switching?
I have all my apps with all pages with public access, anyone can request secured pages: I use an interceptor on the client checking the login state to prevent routing (redirect to home) and on server checking also the user is logged when requesting secured data.
Yes this sounds like a good option when the app/page size is irrelevant :)
@pavlexander you can exclude secured pages from the sw precache manifest (will not work on offline, but also you cannot login into the app) or you can protect the data on that pages (loading data before routing to the page and/or prevent that transition: you will need to protect on the server, no matter if the page can be fetched or not).
currently there is a beforeRoute
guard that redirects the users to the home page if no login session is detected. Hence none of the protected resources are loaded under any circumstances (non-pwa version of the site). Out of curiosity - could you link the documentation page where the "you can exclude secured pages from the sw precache manifest" is explained? I could not find anything on this topic. As I understood all the files that are built are auto-included.
For testing purposes I have set the following plugin config:
VitePWA({
//...
workbox: {
globPatterns: ["**/*.{js,css}"],
},
//...
}),
Default value was globPatterns: ["**/*.{js,css,html}"],
. (according to https://developer.chrome.com/docs/workbox/reference/workbox-build/#type-GlobPartial)
After the build - I can still find the html
file in a precache list:
{ revision: "be53e918256068bde0ecb0f935d98b65", url: "index.html" },
So it seems like property override has no effect. Am I doing something wrong?
Edit: neither did the globIgnores: ["**/SecurePage*"],
work..
{ revision: null, url: "assets/SecurePage.86b6aeec.js" },
@pavlexander SEO here is not involved, the sw will precache all the manifest entries on a background thread, it will take more time to be ready/update when the app is huge, but should not be a problem: lighthouse can be wrong including that resources on the results.
EDIT: as an example you can take a look at vueuse
docs where you have a ton of pages on the sw (also using vite-plugin-pwa
). You can open the dev tools before entering on the page, you will see the app is working while the background thread is precaching (downloading) all the assets, it will take time, just wait to the sw activated and ready (green status on application > Service Workers on dev tools)
For the custom sw, you can write it using TypeScript with static imports using injectManifest
strategy on the pwa plugin configuration instead using old importScript
, you only need to write the sw: check the examples/vue-router/src/claims-sw.ts
, you can also read the Workbox > injectManifest
entry on the docs.
To exclude some pages from the sw you need to use workbox.navigateFallbackDenylist
entry, it is an array of regex, for example:
workbox: {
navigateFallbackDenylist: [/^\/securePage/],
/* more options */
}
EDIT: about excluding index.html
do not this since it is the fallback and must be included on the sw manifest, the browser will complain when installing the sw if missing.
The reason I was thinking about is the SEO optimization. There are 21 pages on production environment that are secured by authentication. Total size of these files are 512kb (for JS) at this moment (+15kb CSS). So, in theory, I could save around 0.5mb of data for every single page viewing requests for every user. As well as for google bot and other crawlers, hence resulting in higher site rankings.
The sw will prefetch all assets only once or when updated found, if you navigate once sw activated the browser will never request the page to the server, the sw will respond with the cache (stale while revalidate): only a hard refresh from the browser will reload the current server page and its assets, but the sw will never download again the sw precache, since it will be updated (of course if you have a new version on the server, all new assets will be downloaded in the background thread).
Just try with the docs of this plugin, or with vueuse docs: once sw activated, just clear the network tab on dev tools, press F5 or Crtl/Command + F5 to do a hard refresh.
EDIT: as an example you can take a look at
vueuse
docs where you have a ton of pages on the sw (also usingvite-plugin-pwa
). You can open the dev tools before entering on the page, you will see the app is working while the background thread is precaching (downloading) all the assets, it will take time, just wait to the sw activated and ready (green status on application > Service Workers on dev tools)
Great example! It really is loading resources on the background! I thought it's all done on initial page load synchronously. In this case SEO should not be a concern. A bunch of unnecessary files downloaded? Maybe. I will have to do the re-prioritization :)
For the custom sw, you can write it using TypeScript with static imports using
injectManifest
strategy on the pwa plugin configuration instead using oldimportScript
, you only need to write the sw: check theexamples/vue-router/src/claims-sw.ts
, you can also read theWorkbox > injectManifest
entry on the docs.To exclude some pages from the sw you need to use
workbox.navigateFallbackDenylist
entry, it is an array of regex, for example:workbox: { navigateFallbackDenylist: [/^\/securePage/], /* more options */ }
EDIT: about excluding
index.html
do not this since it is the fallback and must be included on the sw manifest, the browser will complain when installing the sw if missing.
It was not my intent to exclude the index.html
. I used it to check if the globPatterns
tag is working at all or not. Seems like not. Could you please elaborate on workbox configuration?
I've tried following your advice with following configuration:
workbox: {
navigateFallbackDenylist: [
"**/SecurePage*",
"/SecurePage",
"/SecurePage",
/^\/securePage/,
/^\/SecurePage/,
"^[^ ]*SecurePage",
/[^ ]*SecurePage/,
/[^ ]*SecurePage[^ ]*/,
],
globIgnores: [
"**/SecurePage*",
"/SecurePage",
"/SecurePage",
/^\/securePage/,
/^\/SecurePage/,
"^[^ ]*SecurePage",
/[^ ]*SecurePage/,
/[^ ]*SecurePage[^ ]*/,
],
},
Upon opening the sw.js in distribution folder I can see that the SecurePage is still found among the precache manifest list:
We can further verify it by cleaning old caches, unregistering the service, refreshing the page and forcing the service to create new caches:
So for some reason this navigateFallbackDenylist
tag has no effect. Similarly, I tried using the globPatterns
and globIgnores
but the values that I set are ignored. Is this a bug or did I screw the configuration up somehow?
Then you can exclude all from globIgnored option on worbox, but keep also the deny list option.
Upps, you have it configured, it should be a glob expression. If not working you can use manifestTransforms callback option removing the entries yourself, check pwa-configuration.js on the sveltekit example in this repo.
EDIT: https://github.com/antfu/vite-plugin-pwa/blob/main/examples/sveltekit-pwa/pwa-configuration.js#L52
You should filter the entries by url, ignore the logic for sveltekit.
I ended up configuring my own script to transform the sw.js file with pure workbox solution, no addons. This way I get a better control of what's happening.
@pavlexander can you share your SW configuration to see how you did it without vite pwa plugin ?
I am developing a
vuejs3
app withvite
andvite-plugin-pwa
plugin. The app is login-protected. Therefore whoever opens the webpage - should not have to load all of the pages of the application right away. Only authenticated users should have all of the app components pre-cached.By default -
vite-plugin-pwa
caches all of the pages, including the JS assets fromassets
folder, where lazy-loaded views reside.Here is the example router config I am using:
In the example above the views Home and PublicPage are accessible by any user. On the other hand the SecurePage is only accessible by authenticated users (this logic is in other place so you have to believe me :) ).. The
npm run build command
outputs following files in assets folder:I would like the PWA to cache SecurePage at the later time. So, my question is - how should I approach this problem?
message
event to inform the service worker that some additional pages need to be cached. Is this correct?js
files underassets
folder? ( I couldn't not find any documentation about it)In general it would be nice to see some code samples, if not of the whole solution, then at least of the methods, events that need to be modified or invoked :)
sw.js
vite.config.js
package.json