Bug 183086 - ServiceWorkerRegistration.onupdatefound not called after reload
Summary: ServiceWorkerRegistration.onupdatefound not called after reload
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Service Workers (show other bugs)
Version: Safari Technology Preview
Hardware: All All
: P2 Major
Assignee: Nobody
URL: https://codepen.io/brendonsled/projec...
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-02-23 10:19 PST by Brendon Sled
Modified: 2018-02-24 15:42 PST (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Brendon Sled 2018-02-23 10:19:34 PST
ServiceWorkerRegistration.onupdatefound is never called on a reload when the service-worker.js has been changed.


Running the following in Chrome
https://codepen.io/brendonsled/project/editor/ZgYYOe (fork to modify)

On the first load both Chrome and Safari successfully cache properly as noted by the console.log
Content is cached for offline use.

Upon changing the service-worker.js content Chrome successfully receives the onupdatefound as noted by the console.log
New content is available; please refresh.

Where Safari doesn't receive any onupdatefound
Comment 1 Radar WebKit Bug Importer 2018-02-23 23:33:21 PST
<rdar://problem/37851050>
Comment 2 Chris Dumez 2018-02-24 09:27:53 PST
Looking at the example, it is not obvious to me that the service worker script changes. If it has not changed, why would we fire updatefound?

Per https://w3c.github.io/ServiceWorker/#update-algorithm step 8, if the script URL has not changed and the new source code is the same, then abort.

Or am I missing something? How do you make the service worker script changes? We have tests that use a python script to generate a different source code every time and they seem to PASS (fire update event).
Comment 3 Chris Dumez 2018-02-24 10:16:33 PST
register() [1] says to call Start Register [2]. This schedule a Register [3] job. Step 5.3. says:
"""
If newestWorker is not null, job’s script url equals newestWorker’s script url, and job’s update via cache mode's value equals registration’s update via cache mode, then:

Invoke Resolve Job Promise with job and registration.
Invoke Finish Job with job and abort these steps.
"""

This is what we do here. In your example, you merely register. There is already a registration with same scope / scriptURL and the updateViaCache mode is the same, so we return this registration without updating.

We behave as per spec.

An update would happen if the script explicitly calls update(), or when the service worker intercepts a load (due to Soft Update [4]).

If Chrome behaves differently then the spec does not match Chrome. We may want to file a bug against the spec (or Chrome?).

[1] https://w3c.github.io/ServiceWorker/#navigator-service-worker-register
[2] https://w3c.github.io/ServiceWorker/#start-register
[3] https://w3c.github.io/ServiceWorker/#register-algorithm
[4] https://w3c.github.io/ServiceWorker/#soft-update-algorithm
Comment 4 Chris Dumez 2018-02-24 10:17:41 PST
Please feel free to reopen if you think I misinterpreted the spec or missed something.
Comment 5 Brendon Sled 2018-02-24 14:52:26 PST
Sorry I wasn't clear.

This error is when the page is loaded with a new source code change of the service worker.

(You can see this behavior on the codepen snippet by modifying the serivce-worker.js and reloading the screen)

There is no onupdatefound triggered in this case.

Due to this there is no way to tell on a page reload if the service worker has been updated.

Because of this bug if we have cached content we can not inform the user to reload the page again to use the latest content.
Comment 6 Brendon Sled 2018-02-24 15:42:36 PST
I fixed this by removing ServiceWorkerGlobalScope.skipWaiting