-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Historically, <link rel=prefetch href=url> would tell the browser to consider fetching url, and then if the browser needed url for anything it would be available. As browsers have changed how they fetch resources, however, this is no longer so simple. A browser with a partitioned cache typically has a different cache key for https://a.example when it's a top-level page vs an iframe. When it sees a prefetch, it needs to pick which key to use.
This means <link rel=prefetch href="https://a.example"> can support
<iframe src="https://a.example"> or window.location='https://a.example' but not both.
Here are two demonstration pages with <link rel=prefetch>:
- https://www.jefftk.com/test/prefetch/prefetch-iframe
- https://www.jefftk.com/test/prefetch/prefetch-top-navigation
Both prefetch, wait five seconds, then attempt to use the prefetched result. The first uses the prefetch to populate an iframe while the second uses it for navigation.
I tested on Chrome, Firefox, and Safari. (Safari normally doesn't respect link prefetch. This is with Develop > Experimental Features > LinkPrefetch on.) Here's whether the prefetch is used (no additional network request on the wire):
| Browser | iframe | top navigation |
|---|---|---|
| Chrome | double fetch | double fetch |
| Firefox | prefetch used | double fetch |
| Safari | double fetch | prefetch used |
If we include as=document, Chrome does use the prefetch while Safari and Firefox ignore the attribute and behave as before:
- https://www.jefftk.com/test/prefetch/prefetch-iframe-as-document
- https://www.jefftk.com/test/prefetch/prefetch-top-navigation-as-document
| Browser | iframe as=document | top navigation as=document |
|---|---|---|
| Chrome | double fetch | prefetch used |
| Firefox | prefetch used | double fetch |
| Safari | double fetch | prefetch used |
One way to fix this would be to allow sites to make their intention clear. The fetch spec has an iframe destination, so we could use that: as=iframe. Then we could spec as=document as being for top-level navigation only.