Does link prefetching work across subdomains?
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:
Here's the same resource with prefetching disabled:
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 ответа
Я могу только догадываться. Уверенный ответ, наверное, сможете найти только вы, экспериментально. Слишком много переменных, которые нужно учитывать. Но вот несколько идей:
prefetch
это подсказка для браузера. Браузер может игнорировать это по произвольным причинам. Более того, у него самый низкий приоритет.- Например, на всякий случай проверьте настройки вашего браузера:
Menu/Settings/Advanced/Privacy and security/Preload pages for faster browsing and searching
(или что-то подобное). - Если вы случайно используете мобильный Интернет, это тоже может быть проблемой.
https://www.technipages.com/google-chrome-prefetch - Как быстро вы переходите от целевой страницы к
example.com
? - Проверьте журналы вашего сервера, чтобы узнать, получает ли он когда-нибудь
prefetch
Запросы. Проверьте, не устанавливает ли ваш сервер какие-то странные заголовки в ответ на
prefetch
Запросы. НапримерCache-Control: no-cache
. Да, я вижу, что у вас естьcache-control: max-age=31536000
, поэтому было бы действительно странно, если бы сервер отправил другой заголовок для одного и того же запроса (ну... почти то же самое, по крайней мере, вы не сказали, что они есть, и, по крайней мере, могут быть некоторые заголовки, указывающие, что это аprefetch
запрос), но случаются странные вещи.Вероятно, вам стоит попробовать добавить
crossorigin
атрибут. Например<link rel="prefetch" href="https://example.com/app.css" as="style" crossorigin />
Здесь https://www.w3.org/TR/resource-hints/ вы можете найти этот пример
<link rel="preconnect" href="//example.com"> <link rel="preconnect" href="//cdn.example.com" crossorigin>
весьма актуально для вашего случая, но, к сожалению, без объяснения причин.
В исходной версии вашего вопроса вы упомянули работников службы поддержки... Если они что-то загружают или даже сами загружают что-то вручную, это тоже может быть проблемой. Из-за самого низкого приоритета
prefetch
Если вы загружаете что-то с помощью Mozilla, предварительная загрузка ссылок будет отложена до завершения фоновых загрузок.
Думаю, то же самое и с Chrome.
Вы пытались переместить свою целевую страницу в корневой домен? Если да, и
prefetch
работает должным образом, тогда да - субдомен является причиной проблемы. И сообщение GUIStatus Code: 200 (from prefetch cache)
это наверное просто глюк. Потому что совсем недавно кое-что начало меняться вprefetch
поведение в Chrome. И я пока не знаю, уладилось ли дело. В принципе, да, есть определенная вероятность, что вы сможетеprefetch
только из того же происхождения.https://docs.google.com/document/d/1bKGDIePAuF6YXmmrwM33LeLvtuCsla3vTspsxsNp-f8/edit
Вы должны добавить код ниже, если вы являетесь субдоменом и хотите, чтобы ресурс из домена
<link rel="preconnect" href="https://example.com">
Добавление <link rel=prefetch>
на веб-страницу указывает браузеру загрузить целые страницы или некоторые ресурсы (например, сценарии или файлы CSS), которые могут понадобиться пользователю в будущем. Это может улучшить такие показатели, как "Первая отрисовка содержимого" и "Время до интерактивности", и часто может заставить последующие элементы навигации загружаться мгновенно.
Подсказка предварительной выборки потребляет дополнительные байты для ресурсов, которые не нужны немедленно, поэтому эту технику необходимо применять с умом; выполнять предварительную загрузку ресурсов только тогда, когда вы уверены, что они понадобятся пользователям. Не рекомендуется выполнять предварительную выборку, когда пользователи используют медленное соединение. Вы можете обнаружить это с помощью API сетевой информации.
Есть разные способы определить, какие ссылки нужно предварительно выбрать. Самый простой - предварительно выбрать первую ссылку или несколько первых ссылок на текущей странице. Существуют также библиотеки, использующие более сложные подходы, которые будут объяснены позже в этой публикации - https://web.dev/link-prefetch/.