Service Worker Fetch Handler adds an excessive overhead to fetch events it doesn't handle |
|||
Issue description
We are experimenting with deploying a ServiceWorker on Facebook.com. We intend to use it to enable better caching ("application shell") for faster load times, as well as offline capability in the future.
However, Facebook.com issues a lot of Fetch requests that cannot be cached by its Service Worker and we found that if a ServiceWorker fetch handler is installed, all fetches (script and DOM resources) get routed via the service worker and it creates a significant load time regression.
To illustrate this performance overhead in a reproducible way, I have created a representative micro benchmark:
https://github.com/bgirard/fb_loading_microbench
It includes a SW implementation that serves a basic app shell via readable stream and requires 40 JS resources to be loaded.
Looking at the microbenchmark, it becomes apparent that the Fetch handler imposes a significant performance overhead for fetching resources from the HTTP cache.
I also wrote a tiny Chrome patch (linked below) to simulate the benefits of the proposal in Issue 1026 [1] to allow the page to explicitly bypass the ServiceWorker on some fetch requests:
https://github.com/bgirard/fb_loading_microbench/blob/master/sw_skip_js.patch
Timings from the benchmark, i.e. time from start of page load to having executed the last (40th) JS file:
Resources in HTTP cache, no SW: 1327ms
Resources in HTTP cache, SW enabled but not started: 1735ms
Resources in HTTP cache, SW enabled but not started, bypassed for JS sub-resources: 1356ms
Resources in HTTP cache + reloading page, no SW: 573ms
Resources in HTTP cache + reloading page, SW enabled and started: 566ms
Resources in HTTP cache + reloading page, SW enabled and started, bypassed for JS sub-resources: 530ms
In the last 2 configurations above, the SW is already started and it's able to deliver the app shell quickly. Fetch begin ~30ms earlier in those 2 configurations but the per-resource fetch overhead overwhelms this initial win over 40 resources.
Ideally this SW fetch overhead can be fixed in Chrome, and this could probably be a good test case, otherwise this can be mitigated by the proposal in Issue 1026 [1].
[1] https://github.com/w3c/ServiceWorker/issues/1026
,
Aug 10
,
Aug 20
Hi bgirard, I started looking into this. Are the times in your report from the output like "exec res39.js @ 49.00000058114529" in DevTools?
,
Aug 20
Most numbers come from resource timings, exec comes from a performance.now() call in the script. I don’t create DevTools marks/intervals. If it would help I’m happy to provide an update.
,
Aug 21
Hi! I was just trying to verify how to use the benchmark. Are the times reported above from the the "Script Exec" table for "res39.js"? (I see those are aligned with the console.log output.) On my workstation, I'm getting numbers like 30-60ms when the SW is installed which is quite a bit different from the 500-1000ms above.
,
Sep 27
Yes, the "script exec" table are the right numbers, bgirard is looking at the last number in that column which is when the 40th script starts executing. bgirard, I'm going to close this for now. I just tried to repro this with Chrome 70.0.3538.16 and I'm not seeing any regression like this. Let's reopen it with more repro detail if someone can still reproduce this. |
|||
►
Sign in to add a comment |
|||
Comment 1 by falken@chromium.org
, Mar 8 2018