Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[docs] add service-worker example #7461

Merged
merged 7 commits into from Nov 28, 2022
Merged

[docs] add service-worker example #7461

merged 7 commits into from Nov 28, 2022

Conversation

dummdidumm
Copy link
Member

@dummdidumm dummdidumm commented Nov 1, 2022

Decided against a service worker in the demo app because as @benmccann points out that get's really confusing/annoying really quickly. This PR previously contained a service worker in the demo app, and I got confused for a moment when running another app in preview mode getting served the old demo app, so I threw it out.
Closes #2246

Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
  • This message body should clearly illustrate what problems it solves.
  • Ideally, include a test that fails without this PR but passes with it.

Tests

  • Run the tests with pnpm test and lint the project with pnpm lint and pnpm check

Changesets

  • If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. All changesets should be patch until SvelteKit 1.0

@changeset-bot
Copy link

changeset-bot bot commented Nov 1, 2022

⚠️ No Changeset found

Latest commit: beb11c9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@benmccann
Copy link
Member

I'm not sure how I feel about this. Service workers stick around in the browser so if you run one app with a service worker and then run a different app the service worker from the previous one is still there so it's a very strong form of caching. It makes debugging so much more annoying because I'm constantly having to remove service workers from reproduction reports and sometimes forget it's needed and it confuses users who don't know it will be happening. Personally I'm not sure I would add a service worker at all, but if we do I'd at least argue for it to be an option with a default value of false.

@dummdidumm
Copy link
Member Author

The service worker hanging around resulting in confusion is a good point - but don't you have that problem anyway as soon as you use any form of service-worker? Also, it's only for the demo app. What if we prefix the file with an underscore and add a comment to the file and the about page that you need to "opt in" to the service worker, and why we do that?

@benmccann
Copy link
Member

Yes, you'd probably have that problem with any form of service worker. Making it unused would be fine. Perhaps it would be clearer to call it something like disabled-service-worker.js than an underscore prefix?

@dummdidumm dummdidumm changed the title [feat] add service-worker to demo app [docs] add service-worker example Nov 3, 2022
@dummdidumm
Copy link
Member Author

Removed the service worker from the demo, more details in the PR description

Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>

Because service workers need to be bundled (since browsers don't yet support `import` in this context), **SvelteKit's service workers only work in the production build, not in development**, since it depends on the client-side app's build manifest. To test it locally, use `vite preview` after running a build.

SvelteKit's service worker implementation is deliberately low-level. If you need a more full-flegded but also more opinionated solution, we recommend looking at solutions like [Vite PWA plugin](https://vite-pwa-org.netlify.app/frameworks/sveltekit.html), which uses [Workbox](https://web.dev/learn/pwa/workbox). For more general information on service workers, we recommend [the MDN web docs](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could add a heading here to make it linkable from above

Suggested change
SvelteKit's service worker implementation is deliberately low-level. If you need a more full-flegded but also more opinionated solution, we recommend looking at solutions like [Vite PWA plugin](https://vite-pwa-org.netlify.app/frameworks/sveltekit.html), which uses [Workbox](https://web.dev/learn/pwa/workbox). For more general information on service workers, we recommend [the MDN web docs](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers).
## External solutions
SvelteKit's service worker implementation is deliberately low-level. If you need a more full-flegded but also more opinionated solution, we recommend looking at solutions like [Vite PWA plugin](https://vite-pwa-org.netlify.app/frameworks/sveltekit.html), which uses [Workbox](https://web.dev/learn/pwa/workbox). For more general information on service workers, we recommend [the MDN web docs](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that the section isn't very big I'm not sure we need this. "On this page" would look rather empty, and the only entry being "External Solutions" feels kinda weird. So if we want to, we would need another heading somewhere.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, that's a fair point. other ideas for headings could be:

  • creation
  • registration (probably a sub-heading of the previous one)
  • example

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try to release the pwa plugin for kit next week. I need to merge a few PR and publish a New pwa plugin version before releasing pwa plugin integrations.
With vite-pwa/vite-plugin-pwa#390 we can use something similar to kit sw, just check the sw in the PR example.

Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
Comment on lines 46 to 50
async function deleteOldCaches() {
const keyList = await caches.keys();
const cachesToDelete = keyList.filter((key) => key !== CACHE_NAME);
await Promise.all(cachesToDelete.map((key) => caches.delete(key)));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless something has gone wrong, we should only ever need to delete a single old cache (and in any case, it should be a very fast operation) so i think we can use this theoretically-slower-but-in-practice-identical code which I think is a little easier to parse

Suggested change
async function deleteOldCaches() {
const keyList = await caches.keys();
const cachesToDelete = keyList.filter((key) => key !== CACHE_NAME);
await Promise.all(cachesToDelete.map((key) => caches.delete(key)));
}
async function deleteOldCaches() {
for (const key of await caches.keys()) {
if (key !== CACHE_NAME) await caches.delete(key);
}
}

Comment on lines 62 to 76
async function cacheFirst(request) {
const responseFromCache = await caches.match(request);
if (responseFromCache) {
return responseFromCache;
}
const response = await fetch(request);
addToCache(request, response.clone());
return response;
}

event.respondWith(cacheFirst(event.request));
});
```

> Careful with caching too much for too long! Browsers have a limit on the amount they cache, and not everything should be cached, for example requests that contain dynamic data that change over time
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since people are likely to just copy whatever we put in the docs, I'm not sure we should use a cache-first strategy here — it's a footgun. Cache-first makes sense for build and files, but for pages we should probably have a network-first strategy instead (and I think we should only fall back to the cache for GET requests?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@userquin userquin Nov 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* network-first strategy

* only cache 200 responses
@Rich-Harris Rich-Harris merged commit 0984794 into master Nov 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Default Service Worker (in demo app or/and docs)
4 participants