What is the use of `self.Clients.claim()`

2019-02-12 23:40发布

问题:

To register a service worker, I can call

navigator.serviceWorker.register('/worker.js')

Every time the page loads it checks for an updated version of worker.js. If an update is found, the new worker won't be used until all the page's tabs are closed and then re-opened. The solution I read was:

self.addEventListener('install', function(event) {
  event.waitUntil(self.skipWaiting());
});
self.addEventListener('activate', function(event) {
  event.waitUntil(self.clients.claim());
});

I can understand the skipWaiting part, but what exactly does clients.claim() do? I've done some simple tests and it seems to work as expected even without it.

回答1:

I'm excerpting the following from a guide to the service worker lifecycle:

clients.claim

You can take control of uncontrolled clients by calling clients.claim() within your service worker once it's activated.

Here's a variation of the demo above which calls clients.claim() in its activate event. You should see a cat the first time. I say "should", because this is timing sensitive. You'll only see a cat if the service worker activates and clients.claim() takes effect before the image tries to load.

If you use your service worker to load pages differently than they'd load via the network, clients.claim() can be troublesome, as your service worker ends up controlling some clients that loaded without it.

Note: I see a lot of people including clients.claim() as boilerplate, but I rarely do so myself. It only really matters on the very first load, and due to progressive enhancement the page is usually working happily without service worker anyway.



回答2:

Service worker takes controls from the next page-reload after its registration. By using self.skipWaiting() and self.clients.claim(), you can ask the client to take control over service worker on the first load itself.

e.g

Let's say I cache a files hello.txt, and again If I make a call for hello.txt it will have make server call even though I have resource in my cache. This is the scenario when I don't use self.clients.claim(). However on making a server call for hello.txt on next page reloads, it will be serving the resource from the cache.

To tackle this problem, I have to use combination of self.skipWaiting() and self.clients.claim() so that service worker starts serving content as soon as it is activated.

P.S:

next page-reload means page revisit.

first load signifies the moment when page is visited for the first time.