Bug 250454 - Duplicate requests due to speculative parsing with active service worker
Summary: Duplicate requests due to speculative parsing with active service worker
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Service Workers (show other bugs)
Version: Safari Technology Preview
Hardware: Mac (Apple Silicon) macOS 13
: P2 Normal
Assignee: youenn fablet
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2023-01-11 06:40 PST by marian.schaub
Modified: 2023-12-14 01:34 PST (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description marian.schaub 2023-01-11 06:40:05 PST
Overview:
We noticed unexpected behavior when requests issued by the speculative parsing functionality are fetched through a service worker. As far as we can tell it seems like the initial request made by the browser to preload a resource, while being stuck on a blocking script for example, is not collapsed with the actual request made by the DOM parser once the resource is encountered in the HTML. This leads to two requests being handed to the service worker and potentially an unnecessary request to the network in case this scenario is not explicitly handled by the developer.

Steps to Reproduce:
We built a simple example page to showcase the behavior:
https://sw-lifecycle-test.app.baqend.com/speculativeParser/index.html

1. Open https://sw-lifecycle-test.app.baqend.com/speculativeParser/index.html in Safari
2. Open the developer console, go to the Network tab and check "Disable Caches"
3. When reloading the page you should see two image requests (test1.jpeg and test2.jpeg). In both cases the Initiator is line 13 from index.html, which is our synchronous blocking script, indicating this was loaded by the speculative parsing feature.
4. Append "?sw=1" to the url (https://sw-lifecycle-test.app.baqend.com/speculativeParser/index.html?sw=1) and reload the page. This should install a simple service worker.
5. Open a Web Inspector for the installed service worker.
6. Reload once more. Now the service worker is active. Now we see a different behavior: test1.jpeg is present twice in the network tab. One Request with the Initiator set to line 13 as before and one additional request with the initiator pointing two line 14, the actual line of the corresponding image tag in the html. For test2.jpg we see one request as before. This is because the service worker implementation explicitly only fetches the request for test1.jpeg and ignores everything else. In the Web Inspector for the service worker you should see two logs for test1.jpeg and only one log for test2.jpeg.

Note: To uninstall the service worker for debugging you can append "sw=0" as a query parameter to the url.

Actual Results:
In most cases we can observe the described scenario. The DOM parser issues two requests per resources loaded by the speculative parsing functionality. In case the service worker fetches the resource these requests do not seem to be collapsed. There were times where this behavior disappeared after several reloads but after restarting the browser it usually reappeared again.

Expected Results:
The DOM parser matches the existing speculative request with the actual resource and collapses the requests, so no second requests reaches the service worker.

Build Date & Hardware:
Safari TP Release 160 (Safari 16.4, WebKit 18615.1.14.3)

Additional Builds and Platforms:
I could also reproduce this locally in my latest stable Safari (Version 16.1 (18614.2.9.1.12)) on my Mac. We additionally tested this through several different Safari and OS versions via Browserstack and the results were the same.
Comment 1 Radar WebKit Bug Importer 2023-01-18 06:41:17 PST
<rdar://problem/104377727>
Comment 2 youenn fablet 2023-01-20 07:32:19 PST
I can only reproduce this in case of Hard Reload and/or in case cache is disabled in web inspector.
@Marian, is it correct?
Comment 3 marian.schaub 2023-02-01 00:32:24 PST
Hey Youenn, sorry for the delayed response. Yes, I tested a bit more with other resources and Hard Reload/Disable Cache does seem to be required for reproducing this behavior.
Comment 4 marian.schaub 2023-02-02 09:02:13 PST
An update from our side: We did a bit more testing and were after all able to reproduce the described behavior without the use of the mentioned settings.

For our initial test setup we also noticed an additional case besides Hard Reload and Disable Cache: We can also reproduce the problem on the first load after installing the service worker. This also happens without the use of Disable Cache. For all subsequent reloads the behavior does not occur as you have pointed out.

We additionally set up another test page which does in general behave similar to our first test but instead of using a cacheable blocking script (main.js) we now use a script which the browser cannot cache (otherScript). Now the behavior is reproducible even without the additional settings and also on subsequent reloads:

1. Open https://sw-lifecycle-test.app.baqend.com/speculativeParser/index2.html?sw=1
2. Open web inspector without checking "Disable Cache" 
3. Reload page

Now we can once again see two requests for each of the resources that are actually fetched by the service worker (test1.jpeg and slowScript), one initiated by the line of the un-cacheable script (otherScript, line 26) and one request initiated by the respective tags (line 27 and 29)
Comment 5 marian.schaub 2023-10-26 00:40:33 PDT
(In reply to youenn fablet from comment #2)
> I can only reproduce this in case of Hard Reload and/or in case cache is
> disabled in web inspector.
> @Marian, is it correct?

Hey Youenn, have you had the chance to revisit the reproduction steps in our latest comment where the "Disable Cache" flag is no longer requiered? I just tested again and it seems the issue is still present in the latest Safari and Technology Preview
Comment 6 youenn fablet 2023-12-13 05:50:20 PST
Pull request: https://github.com/WebKit/WebKit/pull/21729
Comment 7 EWS 2023-12-14 01:34:55 PST
Committed 272024@main (c68a38f2d6eb): <https://commits.webkit.org/272024@main>

Reviewed commits have been landed. Closing PR #21729 and removing active labels.