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.