Предварительная обработка страниц в Chrome для мгновенной навигации по страницам

Опубликовано: 2 декабря 2022 г., Последнее обновление: 22 января 2026 г.

Browser Support

  • Chrome: 109.
  • Край: 109.
  • Firefox: не поддерживается.
  • Сафари: за флагом.

Source

Команда Chrome вернула полную предварительную отрисовку будущих страниц, на которые пользователь, скорее всего, перейдет.

Краткая история предварительной отрисовки

Ранее Chrome поддерживал подсказку ресурса <link rel="prerender" href="/next-page"> , однако она не получила широкого распространения за пределами Chrome и не представляла собой очень выразительный API.

Устаревший способ предварительной отрисовки с использованием подсказки rel=prerender был заменен на `NoState Prefetch` , который вместо этого загружал ресурсы, необходимые для будущей страницы, но не выполнял полную предварительную отрисовку страницы и не запускал JavaScript. `NoState Prefetch` действительно помогает улучшить производительность страницы за счет ускорения загрузки ресурсов, но не обеспечивает мгновенную загрузку страницы, как это было бы при полной предварительной отрисовке.

Команда Chrome вновь внедрила полноценную предварительную отрисовку. Во избежание проблем с существующим использованием и для обеспечения возможности дальнейшего расширения предварительной отрисовки, новый механизм предварительной отрисовки не будет использовать синтаксис <link rel="prerender"...> , который остается в силе для NoState Prefetch, с целью его последующего отказа в будущем.

Как происходит предварительная отрисовка страницы?

Предварительная отрисовка страницы может осуществляться четырьмя способами, каждый из которых направлен на ускорение навигации:

  1. Когда вы вводите URL-адрес в адресную строку Chrome (также известную как «омнибокс»), Chrome может автоматически предварительно отобразить страницу, если он уверен, что вы посетите именно эту страницу, основываясь на вашей предыдущей истории просмотров.
  2. При использовании панели закладок Chrome может автоматически предварительно отобразить страницу, если навести указатель мыши на одну из кнопок закладок.
  3. Когда вы вводите поисковый запрос в адресную строку Chrome, Chrome может автоматически предварительно отобразить страницу результатов поиска, если поисковая система даст на это соответствующее указание.
  4. Сайты могут использовать API правил спекуляции , чтобы программно указывать Chrome, какие страницы следует предварительно отрисовывать. Это заменяет то, что раньше делал <link rel="prerender"...> , и позволяет сайтам заблаговременно предварительно отрисовывать страницу на основе правил спекуляции, установленных на странице. Эти правила могут существовать статически на страницах или динамически внедряться с помощью JavaScript по усмотрению владельца страницы.

В каждом из этих случаев предварительная отрисовка ведет себя так, как если бы страница была открыта в невидимой фоновой вкладке, а затем «активируется» путем замены активной вкладки этой предварительно отрисованной страницей. Если страница активируется до того, как она полностью отрисуется, то ее текущее состояние остается «активным», и она продолжает загрузку, что означает, что вы все еще можете получить хороший старт.

Поскольку предварительно отрисованная страница открывается в скрытом состоянии, ряд API, вызывающих навязчивое поведение (например, запросы), не активируются в этом состоянии и вместо этого откладываются до момента активации страницы. В небольшом числе случаев, когда это пока невозможно, предварительная отрисовка отменяется. Команда Chrome работает над тем, чтобы предоставить API для отображения причин отмены предварительной отрисовки, а также над улучшением возможностей DevTools для упрощения выявления таких крайних случаев.

Влияние предварительной отрисовки

Предварительная отрисовка позволяет загружать страницу практически мгновенно, как показано в следующем видео:

Пример влияния предварительной отрисовки.

Пример сайта и так работает быстро, но даже с учетом этого видно, как предварительная отрисовка улучшает пользовательский опыт. Следовательно, это может напрямую повлиять на основные показатели веб-технологий сайта, обеспечивая практически нулевое время отклика (LCP), снижение времени отклика (CLS) (поскольку любое время отклика при загрузке происходит до первоначального отображения) и улучшение времени отклика (поскольку загрузка должна быть завершена до взаимодействия пользователя с сайтом).

Даже если страница активируется до того, как она полностью загрузится, наличие предварительного запуска должно улучшить процесс загрузки. Если ссылка активируется во время предварительной отрисовки, страница, находящаяся в процессе предварительной отрисовки, переместится в основной фрейм и продолжит загрузку.

Однако предварительная отрисовка использует дополнительную память и пропускную способность сети. Будьте осторожны, чтобы не перегружать страницу предварительным рендерингом, так как это приведет к расходу ресурсов пользователя. Предварительный рендеринг следует выполнять только тогда, когда высока вероятность перехода на данную страницу.

Дополнительную информацию о том, как измерить фактическое влияние на производительность в вашей аналитике, см. в разделе « Измерение производительности» .

Посмотреть прогнозы адресной строки Chrome

В первом случае вы можете просмотреть прогнозы Chrome для URL-адресов на странице chrome://predictors :

На странице «Предсказатели Chrome» отображаются низкие (серый), средние (янтарный) и высокие (зеленый) значения предсказаний на основе введенного текста.
Страница «Прогнозировщики Chrome».

Зеленые линии указывают на достаточную степень уверенности для запуска предварительной отрисовки. В этом примере ввод "s" дает приемлемый уровень уверенности (янтарный), но как только вы введете "sh", Chrome будет иметь достаточную уверенность, чтобы вы почти всегда переходили по адресу https://sheets.google.com .

Этот скриншот был сделан в относительно свежеустановленном Chrome с отфильтрованными прогнозами с нулевой степенью достоверности, но если вы просмотрите свои собственные прогнозы, вы, вероятно, увидите значительно больше записей и, возможно, больше символов, необходимых для достижения достаточно высокого уровня достоверности.

Эти факторы также влияют на предлагаемые варианты в адресной строке, которые вы, возможно, заметили:

Функция автозаполнения в адресной строке Chrome
Функция автозаполнения в адресной строке.

Chrome будет постоянно обновлять свои алгоритмы подсказок на основе вашего ввода и выбора.

  • При уровне достоверности более 30% (отображается желтым цветом) Chrome заблаговременно устанавливает предварительное соединение с доменом, но не выполняет предварительную отрисовку страницы.
  • При уровне достоверности более 50% (отображается зеленым цветом) Chrome предварительно отобразит URL-адрес.

API правил спекуляций

В рамках опции предварительной отрисовки API правил спекуляции веб-разработчики могут вставлять на свои страницы инструкции в формате JSON, чтобы сообщить браузеру, какие URL-адреса следует предварительно отрисовать.

списки URL-адресов

Правила спекулятивного анализа могут основываться на списках URL-адресов:

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["next.html", "next2.html"]
    }
  ]
}
</script>

Правила документа

Правила спекуляции также могут быть «правилами документа» с использованием синтаксиса where . Это позволяет спекулировать на ссылках, найденных в документе, на основе селекторов href (на основе API шаблонов URL ) или селекторов CSS:

<script type="speculationrules">
{
  "prerender": [{
    "where": {
      "and": [
        { "href_matches": "/*" },
        { "not": {"href_matches": "/wp-admin"}},
        { "not": {"href_matches": "/*\\?*(^|&)add-to-cart=*"}},
        { "not": {"selector_matches": ".do-not-prerender"}},
        { "not": {"selector_matches": "[rel~=nofollow]"}}
      ]
    }
  }]
}
</script>

Желание

Browser Support

  • Chrome: 121.
  • Edge: 121.
  • Firefox: не поддерживается.
  • Сафари: за флагом.

Source

Параметр eagerness используется для указания момента срабатывания предположений, что особенно полезно для правил работы с документами:

  • conservative : Это предположение на основе показаний указательного пальца или касания земли.
  • moderate : На настольных компьютерах это выполняет предположения, если вы удерживаете указатель мыши над ссылкой в ​​течение 200 миллисекунд (или по событию pointerdown , если это происходит раньше, а на мобильных устройствах, где нет события hover ,). На мобильных устройствах мы перешли на использование сложных эвристических алгоритмов для области просмотра с августа 2025 года. Сложные эвристические алгоритмы для области просмотра срабатывают через 500 мс после того, как пользователь прекратил прокрутку, для якорей, находящихся в пределах 30% вертикального расстояния от предыдущего нажатия указателя мыши, где якоря как минимум в 0,5 раза больше самого большого якоря в области просмотра. Как описано в этом документе .
  • eager : Раньше эта функция eager работала идентично immediate , но в Chrome 143 она изменилась. На настольных компьютерах она выполняет спекулятивные вычисления, если вы удерживаете указатель мыши над ссылкой в ​​течение 10 миллисекунд. На мобильных устройствах с января 2026 года мы перешли на использование простых эвристических алгоритмов для области просмотра. Простые эвристические алгоритмы для области просмотра срабатывают через 50 мс после того, как якорь попадает в область просмотра.
  • immediate : Этот термин используется для обозначения возможности начать спекуляцию как можно скорее, то есть, как только будут соблюдены правила спекуляции.

По eagerness для правил list установлен параметр immediate . Параметры eager », moderate и conservative позволяют ограничить правила list URL-адресами, с которыми пользователь взаимодействует в рамках определенного списка. Хотя во многих случаях правила document с соответствующим условием where могут быть более подходящими.

По умолчанию для правил document используется conservative eagerness . Учитывая, что документ может состоять из множества URL-адресов, использование immediate для правил document следует применять с осторожностью (см. также раздел об ограничениях Chrome далее).

Выбор оптимальной eagerness зависит от вашего сайта. Для легковесного статического сайта более частое использование механизма спекулятивных запросов может быть незначительным и выгодным для пользователей. Сайты со сложной архитектурой и большим объемом страниц могут предпочесть сократить потери, используя механизм спекулятивных запросов реже, пока не получат более позитивный сигнал о намерениях пользователей, чтобы минимизировать потери.

moderate вариант — это золотая середина, и многим сайтам могло бы пригодиться следующее правило спекуляции, которое предварительно отображало бы ссылку при удержании указателя над ссылкой в ​​течение 200 миллисекунд или при событии pointerdown в качестве базовой, но мощной реализации правил спекуляции:

<script type="speculationrules">
{
  "prerender": [{
    "where": {
      "href_matches": "/*"
    },
    "eagerness": "moderate"
  }]
}
</script>

Предварительная загрузка

Правила спекулятивного поиска также можно использовать для предварительной загрузки страниц без полной предварительной отрисовки. Зачастую это может быть хорошим первым шагом на пути к предварительной отрисовке:

<script type="speculationrules">
{
  "prefetch": [
    {
      "urls": ["next.html", "next2.html"]
    }
  ]
}
</script>

Отрисовка до завершения скрипта

Команда Chrome также работает над добавлением prerender_until_script в API правил спекулятивного отображения (см.: ошибка реализации ). Это будет промежуточным этапом между prefetch и prerender и будет использоваться аналогичным образом:

<script type="speculationrules">
{
  "prerender_until_script": [
    {
      "urls": ["next.html", "next2.html"]
    }
  ]
}
</script>

Подобно функции NoState prefetch эта функция будет предварительно загружать как сам HTML-документ, так и вложенные в него ресурсы. Однако она пойдет дальше и начнет предварительную отрисовку страницы, останавливаясь при обнаружении первого скрипта.

Это означало бы, что для страниц без JavaScript или только с JavaScript в нижнем колонтитуле страница могла бы быть практически полностью предварительно отрисована. Страницы со скриптами в <head> не смогли бы предварительно отрисовываться, но всё равно получили бы преимущества от загрузки подресурсов.

Это позволило бы избежать рисков непредвиденных побочных эффектов от выполнения JavaScript, но при этом обеспечило бы гораздо больший прирост производительности, чем просто prefetch .

ограничения Chrome

В Chrome установлены ограничения, предотвращающие чрезмерное использование API правил спекулятивных вычислений:

рвение Предварительная загрузка Предварительная отрисовка
immediate / eager (мобильный) 50 10
eager (настольный) / moderate / conservative 2 (FIFO) 2 (FIFO)
Ограничения на спекулятивные операции в Chrome.

moderate и conservative настройки, зависящие от взаимодействия с пользователем, работают по принципу «первым пришел — первым вышел» (FIFO) : после достижения лимита новая попытка обработки запроса приведет к отмене самой старой попытки и замене ее более новой для экономии памяти. Отмененная попытка обработки запроса может быть запущена снова — например, при повторном наведении курсора на эту ссылку — что приведет к повторной обработке запроса по этому URL-адресу, вытесняя самую старую попытку. В этом случае предыдущая попытка обработки запроса уже кэшировала все доступные для кэширования ресурсы в HTTP-кэше для этого URL-адреса, поэтому повторная попытка обработки запроса должна иметь меньшую стоимость. Именно поэтому лимит установлен на умеренном уровне — 2. Правила статических списков не запускаются действиями пользователя и поэтому имеют более высокий лимит, поскольку браузер не может определить, какие из них необходимы и когда.

Ограничения immediate и eager также являются динамическими, поэтому удаление элемента скрипта URL-адреса list освободит место за счет отмены удаленных предположений.

Chrome также предотвратит использование спекулятивных вычислений в определенных условиях, в том числе:

  • Save-Data .
  • Режим энергосбережения включен и работает при низком уровне заряда батареи.
  • Ограничения по памяти.
  • Когда параметр "Предварительная загрузка страниц" отключен (что также явно отключается расширениями Chrome, такими как uBlock Origin).
  • Страницы открываются во вкладках в фоновом режиме.

Chrome также не отображает iframe-элементы, совместимые с другими источниками, на предварительно отрисованных страницах до момента их активации.

Все эти условия направлены на снижение негативного воздействия чрезмерных спекуляций, когда они могут нанести ущерб пользователям.

Как добавить правила прогнозирования на страницу

Правила спекулятивного вывода могут быть статически включены в HTML-код страницы или динамически вставлены в страницу с помощью JavaScript:

  • Статически включенные правила прогнозирования : например, новостной сайт или блог могут предварительно отображать самую новую статью, если она часто становится следующим пунктом навигации для значительной части пользователей. В качестве альтернативы, для прогнозирования поведения пользователей при взаимодействии со ссылками можно использовать правила документа с moderate или conservative .
  • Динамически вставляемые правила прогнозирования : они могут основываться на логике приложения, быть персонализированы для пользователя или использовать другие эвристические методы.

Тем, кто предпочитает динамическую вставку на основе таких действий, как наведение курсора или щелчок по ссылке — как это делали многие библиотеки в прошлом с помощью <link rel=prefetch> ` — рекомендуется обратить внимание на правила документа, поскольку они позволяют браузеру обрабатывать многие из ваших сценариев использования.

Правила спекулятивного отображения можно добавить либо в раздел <head> , либо в раздел <body> основного фрейма. Правила спекулятивного отображения во вложенных фреймах не применяются, а правила спекулятивного отображения на предварительно отрисованных страницах применяются только после активации этой страницы.

HTTP-заголовок Speculation-Rules

Browser Support

  • Chrome: 121.
  • Edge: 121.
  • Firefox: не поддерживается.
  • Сафари: за флагом.

Source

Правила спекулятивного выполнения также могут передаваться с помощью HTTP-заголовка Speculation-Rules , а не путем включения их непосредственно в HTML-код документа. Это упрощает развертывание через CDN без необходимости самостоятельного изменения содержимого документа.

В документе возвращается HTTP-заголовок Speculation-Rules , указывающий на местоположение JSON-файла, содержащего правила спекулятивного моделирования:

Speculation-Rules: "/speculationrules.json"

Этот ресурс должен использовать правильный MIME-тип и, если это ресурс из другого источника, пройти проверку CORS.

Content-Type: application/speculationrules+json
Access-Control-Allow-Origin: *

Если вы хотите использовать относительные URL-адреса, возможно, вам стоит включить ключ "relative_to": "document" в ваши правила обработки запросов. В противном случае относительные URL-адреса будут относительными к URL-адресу JSON-файла с правилами обработки запросов. Это может быть особенно полезно, если вам нужно выбрать некоторые или все ссылки с одним источником.

Поле тега правил спекуляций

Browser Support

  • Chrome: 136.
  • Edge: 136.
  • Firefox: не поддерживается.
  • Сафари: за флагом.

Source

Также можно добавлять "теги" в синтаксис JSON правил спекуляции на общем уровне для всех правил спекуляции в наборе правил:

{
  "tag": "my-rules",
  "prefetch": [
    "urls": ["next.html"]
  ],
  "prerender": [
    "urls": ["next2.html"]
  ],
}

Или на уровне отдельных правил:

{
  "prefetch": [
    "urls": ["next.html"],
    "tag": "my-prefetch-rules"
  ],
  "prerender": [
    "urls": ["next2.html"],
    "tag": "my-prerender-rules"
  ],
}

Этот тег затем отражается в HTTP-заголовке Sec-Speculation-Tags , который можно использовать для фильтрации правил спекулятивного моделирования на сервере. HTTP-заголовок Sec-Speculation-Tags может содержать несколько тегов, если спекулятивное моделирование охватывается несколькими правилами, как показано в следующем примере:

Sec-Speculation-Tags: null
Sec-Speculation-Tags: null, "cdn-prefetch"
Sec-Speculation-Tags: "my-prefetch-rules"
Sec-Speculation-Tags: "my-prefetch-rules", "my-rules", "cdn-prefetch"

Некоторые CDN автоматически внедряют правила спекулятивного поиска, но блокируют спекулятивный поиск для страниц, не кэшированных на Edge, чтобы избежать увеличения нагрузки на исходный сервер из-за этой функции. Теги позволяют им идентифицировать спекулятивный поиск, инициированный их набором правил по умолчанию, но при этом позволяют любым правилам, добавленным сайтом, передаваться на исходный сервер.

Теги наборов правил также отображаются в инструментах разработчика Chrome .

Правила спекуляций, поле target_hint

Browser Support

  • Chrome: 138.
  • Edge: 138.
  • Firefox: не поддерживается.
  • Safari: не поддерживается.

Source

Правила прогнозирования также могут включать поле target_hint , содержащее допустимое имя контекста просмотра или ключевое слово, указывающее, где страница ожидает активации предварительно отрисованного контента:

<script type=speculationrules>
{
  "prerender": [{
    "target_hint": "_blank",
    "urls": ["next.html"]
  }]
}
</script>

Эта подсказка позволяет обрабатывать предположения о предварительной отрисовке для ссылок с target="_blank" :

<a target="_blank" href="next.html">Open this link in a new tab</a>

На данный момент в Chrome поддерживаются только "target_hint": "_blank" и "target_hint": "_self" (значение по умолчанию, если не указано) и только для предварительной отрисовки — предварительная загрузка данных не поддерживается.

target_hint необходим только для правил определения urls , поскольку для правил определения документа target известен из самой ссылки.

Правила спекулятивных операций и SPA-соглашения

Правила спекулятивной загрузки данных поддерживаются только для навигации по всей странице, управляемой браузером, а не для одностраничных приложений (SPA) или страниц оболочки приложения . В этих архитектурах не используется загрузка документов, а вместо этого выполняется API-загрузка или частичная загрузка данных или страниц, которые затем обрабатываются и отображаются на текущей странице. Данные, необходимые для этих так называемых «мягких навигаций», могут быть предварительно загружены приложением вне правил спекулятивной загрузки, но они не могут быть предварительно отрисованы.

Правила спекулятивной отрисовки можно использовать для предварительной отрисовки самого приложения с предыдущей страницы. Это может помочь компенсировать некоторые дополнительные затраты на первоначальную загрузку, которые возникают в некоторых одностраничных приложениях. Однако изменения маршрута внутри приложения предварительно отрисовать нельзя.

Правила отладки спекулятивных предположений

См. отдельную статью об отладке правил спекулятивного выполнения , где описаны новые функции инструментов разработчика Chrome, которые помогут в просмотре и отладке этого нового API.

Множественные правила спекуляции

На одну и ту же страницу можно добавить несколько правил спекулятивного отображения, которые будут добавляться к существующим правилам. Таким образом, все перечисленные способы приводят к предварительной отрисовке как файла one.html , так и two.html :

Список URL-адресов:

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html", "two.html"]
    }
  ]
}
</script>

Несколько скриптов speculationrules :

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html"]
    }
  ]
}
</script>
<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["two.html"]
    }
  ]
}
</script>

Несколько списков в рамках одного набора speculationrules

<script type="speculationrules">
{
  "prerender": [
    {
      "urls": ["one.html"]
    },
    {
      "urls": ["two.html"]
    }
  ]
}
</script>

Browser Support

  • Chrome: 127.
  • Edge: 127.
  • Firefox: не поддерживается.
  • Safari: не поддерживается.

Source

При предварительной загрузке или предварительной отрисовке страницы некоторые параметры URL (технически известные как параметры поиска ) могут быть неважны для страницы, фактически доставленной сервером, и использоваться только JavaScript на стороне клиента.

Например, UTM-параметры используются Google Analytics для измерения эффективности кампаний, но обычно не приводят к отправке разных страниц с сервера. Это означает, что page1.html?utm_content=123 и page1.html?utm_content=456 будут отправлять одну и ту же страницу с сервера, поэтому одну и ту же страницу можно повторно использовать из кэша.

Аналогичным образом, приложения могут использовать и другие параметры URL, которые обрабатываются только на стороне клиента.

Предложение No-Vary-Search позволяет серверу указывать параметры, которые не влияют на предоставляемый ресурс, и, следовательно, позволяет браузеру повторно использовать ранее кэшированные версии документа, отличающиеся только этими параметрами. Это поддерживается в Chrome (и браузерах на основе Chromium) для предположений о навигации как при предварительной загрузке, так и при предварительной отрисовке.

Правила спекулятивного выполнения поддерживают использование expects_no_vary_search для указания того, где ожидается возврат HTTP-заголовка No-Vary-Search . Это может помочь избежать ненужных загрузок до получения ответов.

<script type="speculationrules">
{
  "prefetch": [{
    "urls": ["/products"],
    "expects_no_vary_search": "params=(\"id\")"
  }]
}
</script>

<a href="/products?id=123">Product 123</a>
<a href="/products?id=124">Product 124</a>

В этом примере начальный HTML-код страницы /products одинаков для обоих идентификаторов товаров: 123 и 124 Однако содержимое страницы в конечном итоге различается в зависимости от рендеринга на стороне клиента с использованием JavaScript для получения данных о товарах по параметру поиска id . Поэтому мы предварительно загружаем этот URL-адрес, и он должен вернуть HTTP-заголовок No-Vary-Search указывающий на то, что страница может использоваться для любого параметра поиска id .

Однако, если пользователь щелкнет по какой-либо из ссылок до завершения предварительной загрузки, браузер может не получить страницу /products . В этом случае браузер не знает, будет ли она содержать заголовок HTTP No-Vary-Search . В этом случае браузеру остается выбор: либо повторно загрузить ссылку, либо дождаться завершения предварительной загрузки, чтобы проверить, содержит ли она заголовок HTTP No-Vary-Search . Параметр expects_no_vary_search позволяет браузеру знать, что ответ страницы должен содержать заголовок HTTP No-Vary-Search , и дождаться завершения этой предварительной загрузки.

Также можно добавить несколько параметров в expects_no_vary_search , разделяя их пробелом (поскольку No-Vary-Search — это структурированный HTTP-заголовок):

    "expects_no_vary_search": "params=(\"param1\" \"param2\" \"param3\")"

Ограничения правил спекулятивных операций и будущие усовершенствования

Правила, касающиеся предположений, распространяются только на страницы, открытые в одной вкладке, но мы работаем над смягчением этого ограничения .

По умолчанию спекуляции ограничены страницами с тем же источником. Спекуляции на страницах с другим источником (например, https://a.example.com может предварительно отрисовывать страницу на https://b.example.com ) позволяют использовать эту функцию. Для этого страница, на которую воздействуют спекуляции (в данном примере https://b.example.com ), должна включить HTTP-заголовок Supports-Loading-Mode: credentialed-prerender иначе Chrome отменит спекуляцию.

В будущих версиях также может быть разрешена предварительная отрисовка страниц, расположенных на разных сайтах, но в разных источниках, при условии, что для предварительно отрисованной страницы отсутствуют файлы cookie и она поддерживает эту функцию с помощью аналогичного HTTP-заголовка Supports-Loading-Mode: uncredentialed-prerender .

Правила спекулятивного запроса уже поддерживают предварительную выборку данных из разных источников, но опять же, только в том случае, если файлы cookie для домена, находящегося в другом источнике, отсутствуют. Если файлы cookie существуют и пользователь уже посещал этот сайт, то спекулятивный запрос не будет использоваться, и в инструментах разработчика будет отображена ошибка.

Учитывая существующие ограничения, одним из способов улучшения пользовательского опыта как при работе с внутренними, так и с внешними ссылками является предварительная отрисовка URL-адресов с тем же источником и попытка предварительной загрузки URL-адресов с другим источником:

<script type="speculationrules">
  {
    "prerender": [
      {
        "where": { "href_matches": "/*" },
        "eagerness": "moderate"
      }
    ],
    "prefetch": [
      {
        "where": { "not": { "href_matches": "/*" } },
        "eagerness": "moderate"
      }
    ]
  }
</script>

Ограничение, предотвращающее спекуляции между источниками для междоменных ссылок по умолчанию, необходимо для обеспечения безопасности. Это улучшение по сравнению с <link rel="prefetch"> для междоменных ресурсов, которые также не будут отправлять файлы cookie, но все равно попытаются выполнить предварительную загрузку — что либо приведет к пустой предварительной загрузке, которую придется отправлять повторно, либо, что еще хуже, к некорректной загрузке страницы.

Поддержка API для обнаружения правил спекулятивного анализа

Вы можете определить наличие поддержки API правил спекуляции с помощью стандартных проверок HTML:

if (HTMLScriptElement.supports && HTMLScriptElement.supports('speculationrules')) {
  console.log('Your browser supports the Speculation Rules API.');
}

Динамически добавляйте правила спекулятивного прогнозирования с помощью JavaScript.

Это пример добавления правила спекулятивной отрисовки prerender с помощью JavaScript:

if (HTMLScriptElement.supports &&
    HTMLScriptElement.supports('speculationrules')) {
  const specScript = document.createElement('script');
  specScript.type = 'speculationrules';
  specRules = {
    prerender: [
      {
        urls: ['/next.html'],
      },
    ],
  };
  specScript.textContent = JSON.stringify(specRules);
  console.log('added speculation rules to: next.html');
  document.body.append(specScript);
}

На этой странице с демонстрацией предварительной отрисовки вы можете посмотреть пример предварительной отрисовки с использованием API правил спекуляции, включающей вставку JavaScript.

Вставка элемента <script type = "speculationrules"> непосредственно в DOM с помощью innerHTML не зарегистрирует правила спекуляции по соображениям безопасности , и его необходимо добавить, как показано ранее. Однако контент, динамически вставляемый с помощью innerHTML и содержащий новые ссылки, будет подхвачен существующими правилами на странице.

Аналогично, прямое редактирование панели «Элементы» в инструментах разработчика Chrome для добавления элемента <script type = "speculationrules"> не регистрирует правила спекуляции, и вместо этого скрипт для динамического добавления этого элемента в DOM необходимо запускать из консоли, чтобы вставить правила.

Добавьте правила спекулятивного прогнозирования через менеджер тегов.

Для добавления правил спекуляции с помощью менеджера тегов, такого как Google Tag Manager (GTM), необходимо вставлять их через JavaScript, а не добавлять элемент <script type = "speculationrules"> непосредственно через GTM, по тем же причинам, что и упоминалось ранее:

Настройка пользовательских HTML-тегов в Google Tag Manager
Добавление правил спекулятивных операций через Google Tag Manager.

Обратите внимание, что в этом примере используется var , поскольку GTM не поддерживает const .

Отменить правила спекуляций

Удаление правил спекулятивного отображения приведет к отмене предварительной отрисовки. Однако к тому моменту, когда это произойдет, ресурсы, скорее всего, уже будут потрачены на запуск предварительной отрисовки, поэтому рекомендуется не выполнять предварительную отрисовку, если существует вероятность необходимости ее отмены. С другой стороны, кэшированные ресурсы все еще могут быть использованы повторно, поэтому отмена может быть не совсем пустой тратой и может принести пользу будущим спекулятивным отображениям и навигации.

Browser Support

  • Chrome: 138.
  • Edge: 138.
  • Firefox: не поддерживается.
  • Safari: не поддерживается.

Source

Также можно отменить спекулятивные операции, используя HTTP-заголовок Clear-Site-Data с директивами prefetchCache и prerenderCache .

Это может быть полезно при изменении состояния на сервере. Например, при вызове API для добавления товара в корзину или API для входа или выхода из системы.

В идеале эти обновления состояния должны передаваться на предварительно отрисованные страницы с помощью таких API, как Broadcast Channel API , но если это невозможно или до тех пор, пока такая логика не будет реализована, отменить спекулятивное предположение может быть проще.

Правила спекулятивных операций и политика безопасности контента.

Поскольку правила спекулятивного доступа используют элемент <script> , даже если они содержат только JSON, их необходимо включить в Content-Security-Policy в файле script-src если сайт его использует — либо с помощью хеша, либо с помощью nonce.

В атрибут script-src можно добавить новые inline-speculation-rules позволяющие поддерживать внедрение элементов <script type="speculationrules"> из скриптов с хэшами или без кодировки. Это не поддерживает правила, включенные в исходный HTML-код, поэтому для сайтов, использующих строгую политику конфиденциальности (CSP), правила необходимо внедрять с помощью JavaScript.

Обнаружение и отключение предварительной отрисовки

Предварительная отрисовка страниц обычно положительно сказывается на пользовательском опыте, поскольку обеспечивает быструю отрисовку — зачастую мгновенную. Это выгодно как пользователю, так и владельцу сайта, поскольку предварительно отрисованные страницы обеспечивают лучший пользовательский опыт, которого трудно достичь другими способами.

Однако могут быть ситуации, когда предварительная отрисовка страниц нежелательна , например, когда страница меняет свое состояние — либо на основе первоначального запроса, либо на основе выполнения JavaScript на странице.

Включение и отключение предварительной отрисовки в Chrome

Предварительная отрисовка включена только для пользователей Chrome, у которых включена настройка "Предварительная загрузка страниц" в chrome://settings/performance/ . Кроме того, предварительная отрисовка также отключается на устройствах с малым объемом памяти или если операционная система находится в режимах экономии данных или энергосбережения. См. раздел "Ограничения Chrome" .

Обнаружение и отключение предварительной отрисовки на стороне сервера.

Предварительно сгенерированные страницы будут отправлены с HTTP-заголовком Sec-Purpose :

Sec-Purpose: prefetch;prerender

При использовании API правил спекуляции для предварительной загрузки страниц этот заголовок будет установлен просто как prefetch :

Sec-Purpose: prefetch

Серверы могут отвечать на основе этого заголовка, чтобы регистрировать запросы на предварительное отображение, возвращать другой контент или предотвращать предварительную отрисовку. Если возвращается код ответа, не соответствующий запросу на успешное выполнение (то есть, не в диапазоне 200-299 после перенаправлений), то страница не будет предварительно отрисована, и любая предварительно загруженная страница будет отброшена. Также следует отметить, что ответы с кодами 204 и 205 недействительны для предварительной отрисовки , но действительны для предварительной загрузки.

Если вы не хотите, чтобы определенная страница предварительно отображалась, лучший способ гарантировать это — вернуть код ответа, отличный от 2XX (например, 503). Однако для обеспечения наилучшего пользовательского опыта рекомендуется вместо этого разрешить предварительную отрисовку, но отложить любые действия, которые должны происходить только после фактического просмотра страницы, используя JavaScript.

Обнаружение предварительной отрисовки в JavaScript

API document.prerendering возвращает true пока страница находится в процессе предварительной отрисовки. Это может использоваться страницами для предотвращения или задержки определенных действий во время предварительной отрисовки до фактической активации страницы.

После активации предварительно отрисованного документа activationStart параметра PerformanceNavigationTiming также будет установлен на ненулевое значение времени, представляющее собой промежуток времени между началом предварительной отрисовки и фактической активацией документа.

Вы можете добавить функцию для проверки наличия предварительной отрисовки и предварительно отрисованных страниц, например, такую:

function pagePrerendered() {
  return (
    document.prerendering ||
    self.performance?.getEntriesByType?.('navigation')[0]?.activationStart > 0
  );
}

Простейший способ проверить, была ли страница предварительно отрисована (полностью или частично), — открыть инструменты разработчика после активации страницы и ввести в консоли performance.getEntriesByType('navigation')[0].activationStart . Если возвращается ненулевое значение, значит, страница была предварительно отрисована:

В консоли Chrome в инструментах разработчика отображается положительный результат activationStart, указывающий на предварительную отрисовку страницы.
Проверка предварительной отрисовки в консоли.

Когда страница активируется пользователем, просматривающим её, в document будет отправлено событие prerenderingchange , которое затем можно использовать для включения действий, которые ранее запускались по умолчанию при загрузке страницы, но которые вы хотите отложить до фактического просмотра страницы пользователем.

Используя эти API, фронтенд-JavaScript может обнаруживать предварительно отрисованные страницы и соответствующим образом реагировать на них.

Влияние на аналитику

Аналитика используется для измерения активности веб-сайта, например, с помощью Google Analytics для измерения просмотров страниц и событий. Или путем измерения показателей производительности страниц с помощью мониторинга реальных пользователей (RUM) .

Предварительная отрисовка страниц должна происходить только тогда, когда существует высокая вероятность того, что пользователь загрузит эту страницу. Именно поэтому параметры предварительной отрисовки адресной строки Chrome срабатывают только при такой высокой вероятности (более 80% случаев).

However—particularly when using the Speculation Rules API—prerendered pages may have an impact on analytics and site owners may need to add extra code to only enable analytics for prerendered pages on activation, as not all analytics providers may do this by default.

This could be achieved by using a Promise which waits for the prerenderingchange event if a document is prerendering, or resolves immediately if it is now:

// Set up a promise for when the page is activated,
// which is needed for prerendered pages.
const whenActivated = new Promise((resolve) => {
  if (document.prerendering) {
    document.addEventListener('prerenderingchange', resolve, {once: true});
  } else {
    resolve();
  }
});

async function initAnalytics() {
  await whenActivated;
  // Initialise your analytics
}

initAnalytics();

An alternative approach is to delay analytic activities until the page is first made visible, which would cover both the prerendering case, and also when tabs are opened in the background (for example, with right-click and open in new tab):

// Set up a promise for when the page is first made visible
const whenFirstVisible = new Promise((resolve) => {
  if (document.hidden) {
    document.addEventListener('visibilitychange', resolve, {once: true});
  } else {
    resolve();
  }
});

async function initAnalytics() {
  await whenFirstVisible;
  // Initialise your analytics
}

initAnalytics();

While this may make sense for analytics and similar use cases, in other cases you may want more content loaded for those cases, and so may want to use document.prerendering and prerenderingchange to specifically target prerendering pages.

Hold back other content during prerendering

The same APIs discussed previously can be used to hold back other content during the prerender phase. This can be specific parts of JavaScript or whole script elements that you would prefer not to run during the prerender stage.

For example, given this script:

<script src="https://example.com/app/script.js" async></script>

You can change this to a dynamically inserted script element which only inserts based on the previous whenActivated function:

async function addScript(scriptUrl) {
  await whenActivated;
  const script = document.createElement('script');
  script.src = 'scriptUrl';
  document.body.appendChild(script);
}

addScript('https://example.com/app/script.js');

This can be useful to hold back distinct scripts that include analytics, or render content based on state or other variables that can change during the span of a visit. For example, recommendations, or login state, or shopping basket icons could all be held back to ensure the most up to date information is presented.

While this is perhaps more likely to happen more often with the use of prerendering, these conditions are also true for pages loaded in background tabs mentioned previously (so the whenFirstVisible function could be used in place of whenActivated ).

In many cases state should ideally also be checked on general visibilitychange changes—for example, when returning to a page that has been background, any shopping basket counters should be updated with the latest number of items in the basket. So this is not a prerender-specific problem but prerender is just making an existing issue more obvious.

One way that Chrome mitigates some of the need for manually wrapping scripts or functions, is that certain APIs are held back as mentioned previously , and also third-party iframes are not rendered, so it's only content on top of this that is required to be manually held back.

Измерение производительности

For measuring performance metrics, analytics should consider whether it is better to measure these based upon the activation time rather than the page load time that browser APIs will report.

For Core Web Vitals, measured by Chrome through the Chrome User Experience Report , these are intended to measure the user experience. So these are measured based on activation time. This will often result in a 0 second LCP for example, showing this is great way of improving your Core Web Vitals.

From version 3.1.0, the web-vitals library has been updated to handle prerendered navigations in the same way Chrome measures Core Web Vitals. This version also flags prerendered navigations for those metrics in the Metric.navigationType attribute if the page was fully or partially prerendered.

Measure prerenders

Whether a page is prerendered can be seen with a non-zero activationStart entry of PerformanceNavigationTiming . This can then be logged using a Custom Dimension, or similar when logging the page views, for example using the pagePrerendered function described previously :

// Set Custom Dimension for Prerender status
gtag('set', { 'dimension1': pagePrerendered() });
// Initialise GA - including sending page view by default
gtag('config', 'G-12345678-1');

This will allow your analytics to show how many navigation are prerendered compared to other types of navigation, and also allow you to correlation any performance metrics or business metrics to these different navigation types. Faster pages means happier users, which can often have real impact on business measures as our case studies show.

As you measure the business impact of prerendering pages for instant navigations, you can decide whether it is worth investing more effort in using this technology to allow more navigations to be prerendered, or to investigate why pages are not being prerendered.

Measure hit rates

In addition to measuring the impact of pages that are visited after a prerender, it is also important to measure pages that are prerendered and not subsequently visited. This could imply you are prerendering too much, and using up valuable resources of the user for little benefit.

This can be measured by firing an analytics event when speculation rules are inserted—after checking the browser supports prerendering using HTMLScriptElement.supports('speculationrules') —to indicate that prerender was requested. (Note that just because a prerender was requested, does not indicate that a prerender was started or completed as, as noted previously, a prerender is a hint to the browser and it may choose not to prerender pages on user settings, current memory usage, or other heuristics.)

You can then compare the number of these events, to the actual prerender page views. Or alternatively fire another event on activation if that makes it easier to compare.

The "successful hit rate" can then be approximated by looking at the difference between these two figures. For pages where you are using the Speculation Rules API to prerender the pages, you can adjust the rules appropriately to ensure you keep a high hit rate to maintain the balance between using up the users resources to help them, versus using it needlessly.

Be aware that some prerendering may be taking place due to the address bar prerendering and not just your speculation rules. You can check the document.referrer (which will be blank for address bar navigation including prerendered address bar navigations) if you want to differentiate these.

Remember to also look at pages which have no prerenders, as that could indicate these pages are not eligible for prerendering, even from the address bar. That may mean you are not benefiting from this performance enhancement. The Chrome team is looking to add extra tooling to test for Prerender eligibility perhaps similar to the bfcache testing tool , and also potentially add an API to expose why a prerender failed.

Impact on extensions

See the dedicated post on Chrome Extensions: Extending API to support Instant Navigation which details some additional considerations extension authors may need to think about for prerendered pages.

Обратная связь

Prerendering is in active development by the Chrome team, and there are plenty of plans to expand the scope of what has been made available in the Chrome 108 release. We welcome any feedback on the GitHub repo or using our issue tracker , and look forward to hearing and sharing case studies of this exciting new API.

Благодарности

Thumbnail image by Marc-Olivier Jodoin on Unsplash