Skip to content

Timing values are inconsistent across browsers when page is controlled by service worker #199

@philipwalton

Description

@philipwalton

For the v4 launch of the web-vitals JS libary we wanted to add additional attribution timings to the TTFB metric (see: GoogleChrome/web-vitals#458).

We were hoping to be able to expose some timing attribution for service worker latency, but in my testing I found that the workerStart, fetchStart, and requestStart values were very inconsistent across browsers for pages that were controlled by service worker—and even inconsistent within the same browser when comparing pages whose navigation request was handled via service worker (i.e. the fetch event called event.respondWith()) vs. pages controlled by service worker but that didn't respond to navigation requests.

I'm not super familiar with this spec, so it wasn't clear whether the issue is with ambiguity in the spec itself or just in engine implementations of the spec, but regardless I wanted to flag my findings here in the hopes that someone would be able to investigate. Also, I didn't see any Web Platform tests covering service worker behavior for this API (at least based on test names).

Summary of inconsistencies

Note: all of these issues can be reproduced using this demo page: https://nt-sw.glitch.me/

If the fetch event DOES NOT call event.respondWith() for the navigation request:

  • workerStart
    • Chrome & Safari: corresponds to when the SW process started (or zero if it was already started)
    • Firefox: is always 0
  • fetchStart
    • Chrome: corresponds to when the fetch event was dispatched
    • Safari: corresponds to when the fetch listeners have finished running.
    • Firefox: is always 0
  • requestStart
    • Chrome, Safari, & Firefox: corresponds to when fetch event listeners have finished running.

Implications:

  • Safari: SW startup duration cannot be measured accurately because fetchStart - workerStart includes time running the fetch events. fetch event duration also cannot be measured.
  • Firefox: Neither SW startup nor fetch event duration can be measured at all.

If the fetch event DOES call event.respondWith() for the navigation request:

  • workerStart
    • Chrome & Safari: corresponds to when the SW process started (or zero if it was already started)
    • Firefox: is always 0
  • fetchStart
    • Chrome: corresponds to when the fetch event was dispatched
    • Safari: is always 0
    • Firefox: corresponds to when event.respondWith() was called
  • requestStart
    • Chrome: also corresponds to when the fetch event was dispatched (even if there was significant blocking duration within the fetch event before event.respondWith() was called)
    • Safari: is always 0
    • Firefox: corresponds to when event.respondWith() was called

Implications:

  • Chrome: fetch event duration cannot be measured because fetchStart and requestStart report the same time.
  • Safari: Neither SW startup nor fetch event duration can be measured at all.
  • Firefox: SW startup duration cannot be measured accurately because fetchStart - workerStart includes time running the fetch events. fetch event duration also cannot be measured.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions