-
Notifications
You must be signed in to change notification settings - Fork 22.5k
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
Updating "Using Service Worker" page #22682
Conversation
I've done a first pass at it and plan to rework the diagrams before marking this as ready for review. That being written please let me know if you see something in the meantime. |
Summary of changes:
|
7eebfc0
to
d207815
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few nitpicks.
There is one more place, where Github isn't letting me make suggestions, where install
verb is used as a noun: "the install and activation process for a new service worker".
files/en-us/web/api/service_worker_api/using_service_workers/index.md
Outdated
Show resolved
Hide resolved
files/en-us/web/api/service_worker_api/using_service_workers/index.md
Outdated
Show resolved
Hide resolved
files/en-us/web/api/service_worker_api/using_service_workers/index.md
Outdated
Show resolved
Hide resolved
files/en-us/web/api/service_worker_api/using_service_workers/index.md
Outdated
Show resolved
Hide resolved
files/en-us/web/api/service_worker_api/using_service_workers/index.md
Outdated
Show resolved
Hide resolved
Co-authored-by: Onkar Ruikar <[email protected]>
@SphinxKnight this is awesome. I will take a look :). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great update, @SphinxKnight !
|
||
The previous attempt, _AppCache_, seemed to be a good idea because it allowed you to specify assets to cache really easily. However, it made many assumptions about what you were trying to do and then broke horribly when your app didn't follow those assumptions exactly. Read Jake Archibald's (unfortunately-titled but well-written) [Application Cache is a Douchebag](https://alistapart.com/article/application-cache-is-a-douchebag/) for more details. | ||
Service workers fix these issues. Using a service worker you can easily set an app up to use cached assets first, thus providing a default experience even when offline, before then getting more data from the network (commonly known as "offline first"). This is already available with native apps, which is one of the main reasons native apps are often chosen over web apps. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Service workers fix these issues. Using a service worker you can easily set an app up to use cached assets first, thus providing a default experience even when offline, before then getting more data from the network (commonly known as "offline first"). This is already available with native apps, which is one of the main reasons native apps are often chosen over web apps. | |
Service workers fix these issues. Using a service worker you can set an app up to use cached assets first, thus providing a default experience even when offline, before then getting more data from the network (commonly known as "offline first"). This is already available with native apps, which is one of the main reasons native apps are often chosen over web apps. |
|
||
> **Note:** From Firefox 84, AppCache has been removed ({{bug("1619673")}}). It has also been [removed](https://bugs.chromium.org/p/chromium/issues/detail?id=582750) from Chromium 95, and is deprecated in Safari. | ||
A service worker functions like a proxy server, allowing you to modify requests and responses, replace them with items from its own cache. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A service worker functions like a proxy server, allowing you to modify requests and responses, replace them with items from its own cache. | |
A service worker functions like a proxy server, allowing you to modify requests and responses, or replace them with items from its own cache. |
? Or alternatively "allowing you to modify requests and responses replacing them with items from its own cache." - if "modify" wants to be the same operation as "replace from cache" rather than an alternative.
|
||
Service workers should finally fix these issues. Service worker syntax is more complex than that of AppCache, but the trade-off is that you can use JavaScript to control your AppCache-implied behaviors with a fine degree of granularity, allowing you to handle this problem and many more. Using a Service worker you can easily set an app up to use cached assets first, thus providing a default experience even when offline, before then getting more data from the network (commonly known as [Offline First](https://offlinefirst.org/)). This is already available with native apps, which is one of the main reasons native apps are often chosen over web apps. | ||
> **Note:** Before service workers, a previous attempt at fixing those issues was AppCache. This API has been deprecated and removed from browsers, and should not be used anymore. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we could just omit this note. Surely at this point only historians know about AppCache?
|
||
## Setting up to play with service workers | ||
|
||
These days, service workers are enabled by default in all modern browsers. To run code using service workers, you'll need to serve your code via HTTPS — Service workers are restricted to running across HTTPS for security reasons. GitHub is therefore a good place to host experiments, as it supports HTTPS. In order to facilitate local development, `localhost` is considered a secure origin by browsers as well. | ||
Service workers are enabled by default in all modern browsers. To run code using service workers, you'll need to serve your code via HTTPS — Service workers are restricted to running across HTTPS for security reasons. A server supporting HTTPS is necessary. To host experiments, you can use a service such as GitHub, Netlify, Vercel, etc. In order to facilitate local development, `localhost` is considered a secure origin by browsers as well. | ||
|
||
## Basic architecture | ||
|
||
With service workers, the following steps are generally observed for basic set up: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With service workers, the following steps are generally observed for basic set up: | |
With service workers, the following steps are generally observed for basic setup: |
5. When the `oninstall` handler completes, the service worker is considered installed. | ||
6. Next is activation. When the service worker is installed, it then receives an activate event. The primary use of `onactivate` is for cleanup of resources used in previous versions of a Service worker script. | ||
7. The Service worker will now control pages, but only those opened after the `register()` is successful. In other words, documents will have to be reloaded to actually be controlled, because a document starts life with or without a Service worker and maintains that for its lifetime. | ||
1. The service worker URL is fetched and registered via [`serviceWorkerContainer.register()`](/en-US/docs/Web/API/ServiceWorkerContainer/register). If successful, the service worker is executed in a [`ServiceWorkerGlobalScope`](/en-US/docs/Web/API/ServiceWorkerGlobalScope); this is basically a special kind of worker context, running off the main script execution thread, with no DOM access. The service worker is now ready to process events. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. The service worker URL is fetched and registered via [`serviceWorkerContainer.register()`](/en-US/docs/Web/API/ServiceWorkerContainer/register). If successful, the service worker is executed in a [`ServiceWorkerGlobalScope`](/en-US/docs/Web/API/ServiceWorkerGlobalScope); this is basically a special kind of worker context, running off the main script execution thread, with no DOM access. The service worker is now ready to process events. | |
1. The service worker code is fetched and then registered using [`serviceWorkerContainer.register()`](/en-US/docs/Web/API/ServiceWorkerContainer/register). If successful, the service worker is executed in a [`ServiceWorkerGlobalScope`](/en-US/docs/Web/API/ServiceWorkerGlobalScope); this is basically a special kind of worker context, running off the main script execution thread, with no DOM access. The service worker is now ready to process events. |
(surely it is the file, not the URL, that is fetched)
- [Chrome](https://www.chromium.org/blink/serviceworker/service-worker-faq/) | ||
- [Firefox](https://firefox-source-docs.mozilla.org/devtools-user/application/service_workers/index.html) | ||
- The "Forget about this site" button, available in [Firefox's toolbar customization options](https://support.mozilla.org/en-US/kb/customize-firefox-controls-buttons-and-toolbars), can be used to clear service workers and their caches. | ||
- [Edge](https://learn.microsoft.com/en-us/microsoft-edge/devtools-guide-chromium/service-workers/) | ||
|
||
## See also | ||
|
||
- [The Service Worker Cookbook](https://github.com/mdn/serviceworker-cookbook) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should remove this as it is unmaintained :(
@@ -481,7 +470,7 @@ When no pages are using the current version, the new worker activates and become | |||
|
|||
### Deleting old caches | |||
|
|||
You also get an `activate` event. This is generally used to do stuff that would have broken the previous version while it was still running, for example getting rid of old caches. This is also useful for removing data that is no longer needed to avoid filling up too much disk space — each browser has a hard limit on the amount of cache storage that a given service worker can use. The browser does its best to manage disk space, but it may delete the Cache storage for an origin. The browser will generally delete all of the data for an origin or none of the data for an origin. | |||
You also get an `activate` event. This is generally used to do stuff that would have broken the previous version while it was still running, for example getting rid of old caches. This is also useful for removing data that is no longer needed to avoid filling up too much disk space — each browser has a hard limit on the amount of cache storage that a given service worker can use. The browser does its best to manage disk space, but it may delete the cache storage for an origin. The browser will generally delete all of the data for an origin or none of the data for an origin. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"You also get an activate
event." reads oddly because it sounds like this is the first time we have seen this event but it isn't. Perhaps just:
You also get an `activate` event. This is generally used to do stuff that would have broken the previous version while it was still running, for example getting rid of old caches. This is also useful for removing data that is no longer needed to avoid filling up too much disk space — each browser has a hard limit on the amount of cache storage that a given service worker can use. The browser does its best to manage disk space, but it may delete the cache storage for an origin. The browser will generally delete all of the data for an origin or none of the data for an origin. | |
As we saw in the last section, when you update a service worker to a new version, you'll create a new cache in its `install` event handler. While there are open pages that are controlled by the previous version of the worker, you need to keep both caches, because the previous version needs its version of the cache. | |
Once all pages controlled by the old version of the worker have closed, the new service worker gets an `activate` event, and will subsequently take over control of pages. So this is the time to delete the previous cache. |
? Is that correct? Too short? I thought a lot of the stuff in that para was a bit woolly tbh.
6. Next is activation. When the service worker is installed, it then receives an activate event. The primary use of `onactivate` is for cleanup of resources used in previous versions of a Service worker script. | ||
7. The Service worker will now control pages, but only those opened after the `register()` is successful. In other words, documents will have to be reloaded to actually be controlled, because a document starts life with or without a Service worker and maintains that for its lifetime. | ||
1. The service worker URL is fetched and registered via [`serviceWorkerContainer.register()`](/en-US/docs/Web/API/ServiceWorkerContainer/register). If successful, the service worker is executed in a [`ServiceWorkerGlobalScope`](/en-US/docs/Web/API/ServiceWorkerGlobalScope); this is basically a special kind of worker context, running off the main script execution thread, with no DOM access. The service worker is now ready to process events. | ||
2. Installation of the worker is attempted when service worker-controlled pages are accessed subsequently. An `install` event is always the first one sent to a service worker (this can be used to start the process of populating an IndexedDB, and caching site assets). During this step, the application is preparing to make everything available for use offline. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Installation of the worker is attempted when service worker-controlled pages are accessed subsequently." is this correct? I thought installation happened as soon as the SW was downloaded and parsed (https://web.dev/learn/pwa/service-workers/#lifecycle).
3. When the `oninstall` handler completes, the service worker is considered installed. However, it does not control the pages: pages using other service workers must be closed before it can be activated. | ||
>**Note:** Waiting for other pages to be closed can be bypassed with [`skipWaiting()`](/en-US/docs/Web/API/ServiceWorkerGlobalScope/skipWaiting). | ||
4. Next is activation. When the service worker is installed, it then receives an `activate` event. The primary use of `onactivate` is for cleanup of resources used in previous versions of a service worker script. | ||
5. The service worker will now control pages, but only those opened after the `register()` is successful. In other words, documents will have to be reloaded to actually be controlled, because a document starts life with or without a service worker and maintains that for its lifetime. | ||
6. Whenever a new version of a service worker is fetched, this cycle happens again and the remains of the previous version are cleaned during the new version's activation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lifecycle is for me the hardest part about service workers, and somewhere it's really worth being super clear. Maybe we could say:
3. When the `oninstall` handler completes, the service worker is considered installed. However, it does not control the pages: pages using other service workers must be closed before it can be activated. | |
>**Note:** Waiting for other pages to be closed can be bypassed with [`skipWaiting()`](/en-US/docs/Web/API/ServiceWorkerGlobalScope/skipWaiting). | |
4. Next is activation. When the service worker is installed, it then receives an `activate` event. The primary use of `onactivate` is for cleanup of resources used in previous versions of a service worker script. | |
5. The service worker will now control pages, but only those opened after the `register()` is successful. In other words, documents will have to be reloaded to actually be controlled, because a document starts life with or without a service worker and maintains that for its lifetime. | |
6. Whenever a new version of a service worker is fetched, this cycle happens again and the remains of the previous version are cleaned during the new version's activation. | |
3. When the `install` handler completes, the service worker is considered installed. At this point a previous version of the service worker may be active and controlling open pages. Because we don't want two different versions of the same service worker running at the same time, the new version is not yet active. | |
4. Once all pages controlled by the old version of the service worker have closed, it's safe to retire the old version, and the newly installed service worker receives an `activate` event. The primary use of `activate` is to clean up resources used in previous versions of the service worker. | |
The new service worker can call [`skipWaiting()`](/en-US/docs/Web/API/ServiceWorkerGlobalScope/skipWaiting) to ask to be activated immediately without waiting for open pages to be closed. The new service worker will then receive `activate` immediately, and will take over any open pages. | |
5. After activation, the service worker will now control pages, but only those that were opened after the `register()` is successful. In other words, documents will have to be reloaded to actually be controlled, because a document starts life with or without a service worker and maintains that for its lifetime. To override this default behavior and adopt open pages, a service worker can call [`clients.claim()`](/en-US/docs/Web/API/Clients/claim). | |
6. Whenever a new version of a service worker is fetched, this cycle happens again and the remains of the previous version are cleaned during the new version's activation. |
does that sound right?
But I also wonder if it might be clearer to break out "first time installation" and "update" (because IMO a lot of the complexity comes from update behavior, and presenting them separately means we could build the compexity gradually...)
- [`sync`](/en-US/docs/Web/API/ServiceWorkerGlobalScope/sync_event) | ||
- [`push`](/en-US/docs/Web/API/ServiceWorkerGlobalScope/push_event) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't actually talk about these events (or message
) here. I don't think we have to in this PR but it might be worth covering them in a follow up.
Thanks a lot @wbamberg!! It is far better now :) #simple #easily |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @SphinxKnight for this update! This important page has made me sad for a long time but I never got around to updating it.
* WIP3 * First page * First pass * Parity with mdn/content#22682 * fix md typo * Small typofixes and updates/nitpicking Co-authored-by: cw118 <[email protected]>
Description
Update this page to remove "dated" information.
Motivation
I was translating the page for mdn/translated-content#10371 and was a bit saddened by the original page. So I went with contributing on the English one as well
Related issues and pull requests
mdn/yari#7645
#9679