Does link prefetching work across subdomains?

1.6k views Asked by At

I've been trying to use something like this to get a performance boost when clicking from a simple landing page to a heavyweight single page app:

<link rel="prefetch" href="https://example.com" as="document" />
<link rel="prefetch" href="https://example.com/app.js" as="script" />
<link rel="prefetch" href="https://example.com/app.css" as="style" />

It seems to have no noticeable performance boost when my landing page is on a subdomain. Say, https://subdomain.example.com.

When I click on a link to visit https://example.com, I still see a long delay in the Chrome network tab as app.js and app.css are loaded:

Prefetched resources Resource download time with prefetching

Here's the same resource with prefetching disabled:

Resource download time without prefetching

It takes roughly the same amount of time in total.


Request headers for one of the assets that loaded with prefetch cache:

General:

Request URL: https://example.com/css/app.bffe365a.css
Request Method: GET
Status Code: 200  (from prefetch cache)
Remote Address: 13.226.219.19:443
Referrer Policy: no-referrer-when-downgrade

Response:

accept-ranges: bytes
cache-control: max-age=31536000
content-encoding: gzip
content-length: 39682
content-type: text/css
date: Mon, 06 Jan 2020 21:42:53 GMT
etag: "d6f5135674904979a2dfa9dab1d2c440"
last-modified: Mon, 06 Jan 2020 20:46:46 GMT
server: AmazonS3
status: 200
via: 1.1 example.cloudfront.net (CloudFront)
x-amz-cf-id: dO3yiCoPErExrE2BLYbUJaVye32FIJXXxMdI4neDGzGX9a6gcCDumg==
x-amz-cf-pop: LAX50-C1
x-amz-id-2: 1O0LmihxpHIywEaMQWX7G3FDAzxtH9tZq1T/jeVLMzifFSJSIIJSS6+175H61kKdAq6iEbwfs2I=
x-amz-request-id: AF35C178092B65D4
x-cache: Hit from cloudfront

Request:

DNT: 1
Referer: https://example.com/auth/join
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36

My question is: If Chrome indicates that the prefetch cache is used then why is there a significant content download time?

It seems that Chrome has different kinds of caches: prefetch cache, disk cache and memory cache. Disk cache and memory cache are very fast (5ms and 0ms load times). However prefetch cache is pretty useless with 300ms download times sometimes. Can I get a technical explanation of why this happens? Is it a bug with Chrome? I am on Chrome 79.0.3945.117.

3

There are 3 answers

1
Mohammad Yaseer On

Adding <link rel=prefetch> to a web page tells the browser to download entire pages or some of the resources (like scripts or CSS files), that the user might need in the future. This can improve metrics like First Contentful Paint and Time to Interactive and can often make subsequent navigations appear to load instantly.

enter image description here

The prefetch hint consumes extra bytes for resources that are not immediately needed, so this technique needs to be applied thoughtfully; only prefetch resources when you are confident that users will need them. Consider not prefetching when users are on slow connections. You can detect that with the Network Information API.

There are different ways to determine which links to prefetch. The simplest one is to prefetch the first link or the first few links on the current page. There are also libraries that use more sophisticated approaches, explained later in this post-https://web.dev/link-prefetch/.

4
x00 On

I can only guess. Confident answer probably can be found only by you, through experiment. There are too much variables to account for. But here some ideas:

  1. prefetch is a hint for a browser. Browser can ignore it for some arbitrary reasons. More than that it has the lowest priority.
  2. E.g. just in case, please, check your browser settings:
    Menu/Settings/Advanced/Privacy and security/Preload pages for faster browsing and searching
    (or something like that).
  3. If by any chance you are using mobile internet it also can be a problem.
    https://www.technipages.com/google-chrome-prefetch
  4. How fast do you navigate from your landing page to the example.com?
  5. Check your server logs to see if it ever receives prefetch requests.
  6. Check if your server sets some strange headers in response to prefetch requests. E.g. Cache-Control: no-cache. Yea, I see that you have cache-control: max-age=31536000, so it would be really strange, if the server will send different header for the same request (well... almost the same, at least you did not said that they are, and there at least can be some headers indicating that it is a prefetch request), but strange things happen.

  7. You probably should try to add crossorigin attribute. E.g.

    <link rel="prefetch" href="https://example.com/app.css" as="style" crossorigin />

    Here https://www.w3.org/TR/resource-hints/ you can find this example

    <link rel="preconnect" href="//example.com">
    <link rel="preconnect" href="//cdn.example.com" crossorigin>
    

    quite relevant for your case, but unfortunately with no explanation.

  8. In the original version of your question you mentioned service workers... If they download something, or even yourself manually downloading something, it also can be the issue. Because of the lowest priority of prefetch

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Link_prefetching_FAQ#What_if_I.27m_downloading_something_in_the_background.3F_Will_link_prefetching_compete_for_bandwidth.3F

    If you are downloading something using Mozilla, link prefetching will be delayed until any background downloads complete

    I think same goes for the Chrome.

  9. Have you tried to move your landing page to the root domain? If, yes, and prefetch works as expected, then yes - subdomain is the cause of issue. And GUI message Status Code: 200 (from prefetch cache) is probably just a glitch. Because just recently some things began to change in the prefetch behavior in Chrome. And I do not know yet if things settled out. Basically, yes, there is certain probability that you can prefetch only from the same origin.

    https://docs.google.com/document/d/1bKGDIePAuF6YXmmrwM33LeLvtuCsla3vTspsxsNp-f8/edit

0
divyang4481 On

you should add below code in case you are ont subdomain and you want resource from domain

<link rel="preconnect" href="https://example.com">