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

Поддержка браузера

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

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

Краткая история пререндера

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

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

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

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

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

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

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

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

Влияние предварительного рендеринга

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

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

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

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

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

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

Просмотр подсказок в адресной строке Chrome

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

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

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

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

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

Функция «Ввод текста» в адресной строке Chrome
Функция «Ввод текста» в адресной строке.

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

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

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

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

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

Или с помощью правил документа (доступных в Chrome 121), которые предварительно отображают ссылки, найденные в документе, на основе селекторов 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>

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

рвение

Поддержка браузера

  • Хром: 121.
  • Край: 121.
  • Firefox: не поддерживается.
  • Сафари: не поддерживается.

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

  • immediate : используется для спекуляции как можно скорее, то есть как только будут соблюдены правила спекуляции.
  • eager : ведет себя идентично immediate параметру, но в будущем мы хотим разместить его где-то между immediate и moderate .
  • moderate : выполняются предположения, если вы удерживаете указатель над ссылкой в ​​течение 200 миллисекунд (или при событии pointerdown , если это происходит раньше, и на мобильных устройствах, где нет события hover ).
  • conservative : это спекуляция на указателе или приземлении.

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

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

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

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

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

Предварительная выборка

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

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

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

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

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

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

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

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

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

Chrome также не отображает iframe из разных источников на предварительно обработанных страницах до активации.

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

Как включить правила спекуляции на странице

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

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

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

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

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

Поддержка браузера

  • Хром: 121.
  • Край: 121.
  • Firefox: не поддерживается.
  • Сафари: не поддерживается.

Источник

Правила спекуляции также можно доставить с помощью 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 правил спекуляции. Это может быть особенно полезно, если вам нужно выбрать некоторые или все ссылки одного и того же происхождения.

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

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

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

Отладка правил спекуляций

См. специальный пост, посвящённый отладке правил спекуляций , чтобы узнать о новых функциях Chrome DevTools, помогающих просматривать и отлаживать этот новый 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>

Поддержка браузера

  • Хром: 121.
  • Край: 121.
  • Firefox: не поддерживается.
  • Сафари: не поддерживается.

Источник

При предварительной выборке или предварительной отрисовке страницы некоторые параметры 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 , и ждать завершения этой предварительной выборки.

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

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

По умолчанию спекуляции ограничиваются страницами одного и того же происхождения. Предположение о страницах с перекрестным происхождением на одном и том же сайте (например, 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 существуют от пользователя, который ранее посещал этот сайт, то предположение не будет вызвано и отобразит сбой в DevTools.

Учитывая эти текущие ограничения, один из шаблонов, который может улучшить взаимодействие ваших пользователей как с внутренними, так и с внешними ссылками, где это возможно, — это предварительная обработка 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 Speculation Rules с использованием вставки JavaScript на этой демонстрационной странице предварительной визуализации .

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

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

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

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

Конфигурация пользовательского HTML-тега в Диспетчере тегов Google
Добавление правил спекуляции через Диспетчер тегов Google.

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

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

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

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

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

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

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

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

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

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

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

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

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

Sec-Purpose: prefetch;prerender

На страницах с предварительной выборкой, использующих API Speculation Rules, этот заголовок будет иметь значение «просто 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
  );
}

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

Консоль в Chrome DevTools показывает положительную активацию. Начало указывает на то, что страница была предварительно обработана.
Тестирование пререндера в консоли.

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

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

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

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

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

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

Этого можно достичь с помощью Promise , который ожидает события prerenderingchange , если документ выполняет предварительную отрисовку, или разрешает немедленно, если это происходит сейчас:

// 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();

Альтернативный подход — отложить аналитические действия до тех пор, пока страница впервые не станет видимой, что будет охватывать как случай предварительной отрисовки, так и случаи открытия вкладок в фоновом режиме (например, при щелчке правой кнопкой мыши и открытии в новой вкладке):

// 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();

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

Сдерживайте другой контент во время предварительного рендеринга

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

Например, учитывая этот скрипт:

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

Вы можете изменить это на динамически вставляемый элемент сценария, который вставляется только на основе предыдущей функции whenActivated :

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');

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

Хотя это, возможно, происходит чаще при использовании предварительной отрисовки, эти условия также верны для страниц, загруженных в фоновые вкладки, упомянутые ранее (поэтому вместо функции whenActivated можно использовать функцию whenFirstVisible ).

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

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

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

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

Основные веб-показатели, измеряемые Chrome с помощью отчета об опыте пользователей Chrome , предназначены для измерения пользовательского опыта. Таким образом, они измеряются на основе времени активации. Например, это часто приводит к 0-секундному LCP, показывая, что это отличный способ улучшить ваши основные веб-показатели.

Начиная с версии 3.1.0, библиотека web-vitals была обновлена ​​и теперь обрабатывает предварительно обработанную навигацию таким же образом, как Chrome измеряет основные веб-показатели. Эта версия также помечает предварительно обработанную навигацию для этих метрик в атрибуте Metric.navigationType , если страница была полностью или частично предварительно обработана.

Измерение пререндеринга

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

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

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

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

Измерьте процент попаданий

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

Это можно измерить, запуская событие аналитики при вставке правил спекуляции (после проверки того, что браузер поддерживает предварительную отрисовку с помощью HTMLScriptElement.supports('speculationrules') , чтобы указать, что предварительная отрисовка была запрошена. (Обратите внимание, что тот факт, что была запрошена предварительная отрисовка, не означает, что предварительная отрисовка была начата или завершена, поскольку, как отмечалось ранее, предварительная отрисовка является подсказкой для браузера, и он может отказаться от предварительной отрисовки страниц в настройках пользователя, текущем использовании памяти, или другие эвристики.)

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

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

Имейте в виду, что некоторая предварительная обработка может происходить из-за предварительной обработки адресной строки, а не только из-за ваших правил предположения. Вы можете проверить document.referrer (который будет пустым для навигации по адресу адресной строки, включая предварительную навигацию по адресу адреса), если вы хотите дифференцировать их.

Не забудьте также смотреть на страницы, на которых нет прерандеров, так как это может указывать на то, что эти страницы не имеют права на презривание, даже из адресной панели. Это может означать, что вы не получаете выгоду от этого повышения производительности. Команда Chrome стремится добавить дополнительные инструменты для проверки на право на получение Prerender, возможно, аналогично инструменту тестирования BFCache , а также потенциально добавить API, чтобы раскрыть, почему прерандер потерпел неудачу.

Воздействие на расширения

См. Выделенный пост о расширениях Chrome: расширение API для поддержки мгновенной навигации , в которой подробно описываются некоторые дополнительные соображения, которые авторы расширения, возможно, должны подумать о предварительных страницах.

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

Презендеринг находится в активном развитии команды Chrome, и есть много планов по расширению объема того, что было доступно в выпуске Chrome 108. Мы приветствуем любые отзывы о репо GitHub или использовали наш трекер выпуска , и с нетерпением ждем возможности слушать и поделиться тематическими исследованиями этого захватывающего нового API.

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

Миниатюра изображение Марка-Оливье Джодон на Unsplash

,

Поддержка браузера

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

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

Краткая история прерандера

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

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

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

Как страница преропендирована?

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

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

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

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

Влияние пререндерирования

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

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

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

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

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

См. Раздел измерения производительности для получения дополнительной информации о том, как измерить фактическое воздействие на производительность в вашей аналитике.

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

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

На странице Chrome Predictors отфильтрована показатели низкого (серого), среднего (янтаря) и высоких (зеленых) прогнозов на основе введенного текста.
Хромированные предикторы страница.

Зеленые линии указывают на достаточную уверенность, чтобы вызвать презринг. В этом примере «S» дает разумную уверенность (AMBER), но как только вы напечатаете «SH», тогда Chrome обладает достаточной уверенностью, что вы почти всегда перемещаетесь на https://sheets.google.com .

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

Эти предикторы также приводят к тому, что вы можете заметить, что вы заметили:

Функция Chrome Address Bar 'Typeaead'
Функция адресной панели «typeahead».

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

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

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

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

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

Или по правилам документов (доступны из Chrome 121), которые предварительно предназначены ссылки, найденные в документе на основе селекторов 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>

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

Рвение

Поддержка браузера

  • Хром: 121.
  • Край: 121.
  • Firefox: не поддерживается.
  • Сафари: не поддерживается.

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

  • immediate : это используется для спекуляции как можно скорее, то есть, как только будут соблюдать правила спекуляций.
  • eager : это ведет себя идентично immediate обстановке, но в будущем мы стремимся разместить это где -то между immediate и moderate .
  • moderate : это выполняет предположения, если вы держите указатель по ссылке на 200 миллисекунд (или на событии pointerdown , если это раньше, и на мобильных устройствах, где нет события hover ).
  • conservative : это предполагает указатель или прикосновение вниз.

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

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

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

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

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

Предварительный

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

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

Хромированные ограничения

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

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

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

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

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

  • Сохранить дату .
  • Энергетическая экономия при включении и на низкой батареи.
  • Ограничения памяти.
  • Когда настройка «страниц предварительной нагрузки» выключается (которая также явно выключена с помощью хромированных расширений, таких как Oblock Origin).
  • Страницы открыты на фоновых вкладках.

Chrome также не производит перекрестные иригины на предварительных страницах до активации.

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

Как включить правила спекуляций на странице

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

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

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

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

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

Поддержка браузера

  • Хром: 121.
  • Край: 121.
  • Firefox: не поддерживается.
  • Сафари: не поддерживается.

Источник

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

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

Speculation-Rules: "/speculationrules.json"

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

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

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

Правила спекуляций и спа -салоны

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

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

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

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

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

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

Список 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>

Поддержка браузера

  • Хром: 121.
  • Край: 121.
  • Firefox: не поддерживается.
  • Сафари: не поддерживается.

Источник

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

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

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

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

Поддержка Правил спекуляций с использованием 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>

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

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

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

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

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

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

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

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

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

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

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

Обнаружение правил спекуляций 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 Devtools для добавления элемента <script type = "speculationrules"> не регистрирует правила спекуляций, и вместо этого сценарий для динамического добавления этого в DOM должен быть запущен из консоли для вставки правил.

Добавить правила спекуляций через диспетчер тегов

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

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

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

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

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

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

Поскольку правила спекуляций используют элемент <script> , даже если они содержат только JSON, они должны быть включены в script-src -политическую политику, если сайт использует это,-либо используя хэш или нонс.

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

Обнаружить и отключить презринг

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

Тем не менее, могут быть случаи, когда вы не хотите, чтобы предварительное предварительное преобразование страниц произошло , например, когда страницы изменяют состояние - либо на основе первоначального запроса, либо на основе JavaScript, выполняемого на странице.

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

PRERENDER включен только для тех пользователей Chrome с настройкой «страниц предварительной нагрузки» в chrome://settings/performance/ . Кроме того, Prerender также отключен на устройствах с низкой памяти, или если операционная система находится в режимах сохранения данных или энергии. См. Раздел «Хромированные ограничения» .

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

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

Sec-Purpose: prefetch;prerender

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

Sec-Purpose: prefetch

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

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

Обнаружение Prerender в JavaScript

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

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

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

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

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

Консоль в Chrome Devtools, показывающая положительную активацию, указывающую на то, что страница была предварительно
Тестирование прерандера в консоли.

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

Используя эти API, Frontend JavaScript может правильно обнаружить и действовать на предварительно предварительному страницам.

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

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

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

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

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

// 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();

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

// 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();

Хотя это может иметь смысл для аналитики и аналогичных вариантов использования, в других случаях вы можете захотеть, чтобы больше контента было загружено для этих случаев, и поэтому может захотеть использовать document.prerendering И prerenderingchange , специально предназначенные для предварительных страниц.

Сдерживайте другой контент во время презринг

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

Например, учитывая этот сценарий:

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

Вы можете изменить это на динамически вставленный элемент сценария, который вставляется только на основе предыдущей функции whenActivated :

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');

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

Хотя это, возможно, чаще случается с использованием пререндерирования, эти условия также верны для страниц, загруженных на фоновых вкладках, упомянутых ранее (поэтому, whenFirstVisible использовать функцию, которая может использоваться вместо whenActivated ).

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

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

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

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

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

Из версии 3.1.0 библиотека web-vitals была обновлена ​​для обработки предварительных навигаций так же, как Chrome измеряет основные веб-жизненные данные. Эта версия также отмечает предварительные навигации для этих метрик в атрибуте Metric.navigationType , если страница была полностью или частично презрированной.

Измерить прерандеры

Можно ли увидеть ли страницу с ненулевой activationStart записью PerformanceNavigationTiming . Затем это можно войти в систему с использованием пользовательского измерения или аналогично при регистрации представлений страниц, например, с использованием функции pagePrerendered , описанной ранее :

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

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

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

Измерьте показатели попадания

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.

Acknowledgements

Thumbnail image by Marc-Olivier Jodoin on Unsplash

,

Browser Support

  • Chrome: 109.
  • Edge: 109.
  • Firefox: not supported.
  • Safari: not supported.

The Chrome team has brought back full prerendering of future pages that a user is likely to navigate to.

A brief history of prerender

In the past, Chrome supported the <link rel="prerender" href="/next-page"> resource hint, however it was not broadly supported beyond Chrome, and it wasn't a very expressive API.

This legacy prerendering using the link rel=prerender hint was deprecated in favor of NoState Prefetch , which instead fetched the resources needed by the future page, but did not fully prerender the page nor execute JavaScript. NoState Prefetch does help improve page performance by improving the resource loading, but won't deliver an instant page load like a full prerender would.

The Chrome team has now reintroduced full prerendering back into Chrome. To avoid complications with existing usage, and to allow for future expansion of prerendering, this new prerender mechanism won't use the <link rel="prerender"...> syntax, which remains in place for NoState Prefetch, with a view of retiring this at some point in the future.

How is a page prerendered?

A page can be prerendered in one of four ways, all of which aim to make navigations quicker:

  1. When you type a URL into the Chrome address bar (also known as "the omnibox"), Chrome may automatically prerender the page for you, if it has high confidence you will visit that page, based on your previous browsing history.
  2. When you use the bookmarks bar, Chrome may automatically prerender the page for you on holding the pointer over one of the bookmark buttons.
  3. When you type a search term into the Chrome address bar, Chrome may automatically prerender the search results page, when instructed to do so by the search engine.
  4. Sites can use the Speculation Rules API , to programmatically tell Chrome which pages to prerender. This replaces what <link rel="prerender"...> used to do and allows sites to proactively prerender a page based on speculation rules on the page. These can statically exist on the pages, or be dynamically injected by JavaScript as the page owner sees fit.

In each of these cases, a prerender behaves as if the page has been opened in an invisible background tab, and then is "activated" by replacing the foreground tab with that prerendered page. If a page is activated before it has fully prerendered, then its current state is "foregrounded" and continues to load, which means you can still get a good head start.

As the prerendered page is opened in a hidden state, a number of APIs that cause intrusive behaviors (for example, prompts) are not activated in this state, and are instead delayed until the page is activated. In the small number of cases where this is not yet possible, the prerender is canceled. The Chrome team is working on exposing prerender cancellation reasons as an API, and also enhancing DevTools capabilities to make identifying such edge cases easier.

Impact of prerendering

Prerendering allows a near-instant page load as shown in the following video:

Example impact of prerendering.

The example site is already a fast site, but even with this you can see how prerendering improves the user experience. This can therefore also have a direct impact on a site's Core Web Vitals , with near zero LCP, reduced CLS (since any load CLS happens before the initial view), and improved INP (since the load should be completed before the user interacts).

Even when a page activates before it is fully loaded, having a head start to the page load, should improve the loading experience. When a link is activated while prerendering is still happening, the prerendering page will move to the main frame and continue loading.

However, prerendering does use additional memory and network bandwidth. Be careful not to over-prerender, at a cost of user resources. Only prerender when there is a high likelihood of the page being navigated to.

See the Measuring performance section for more information on how to measure the actual performance impact in your analytics.

View Chrome's address bar predictions

For the first use case, you can view Chrome's predictions for URLs in the chrome://predictors page:

The Chrome Predictors page filtered to show low (grey), medium (amber), and high (green) predictions based on text entered.
Chrome Predictors page.

Green lines indicate enough confidence to trigger prerendering. In this example typing "s" gives a reasonable confidence (amber), but once you type "sh" then Chrome has enough confidence that you nearly always navigate to https://sheets.google.com .

This screenshot was taken in a relatively fresh Chrome install, and filtering out zero confidence predictions, but if you view your own predictors you will likely see considerably more entries, and potentially more characters required to reach a high enough confidence level.

These predictors are also what drive the address bar suggested options you may have noticed:

The Chrome address bar 'Typeahead' feature
Address bar 'Typeahead' feature.

Chrome will continually update its predictors based on your typing and selections.

  • For a greater than 50% confidence level (shown in amber), Chrome proactively preconnects to the domain, but does not prerender the page.
  • For a greater than 80% confidence level (shown in green), Chrome will prerender the URL.

The Speculation Rules API

For the Speculation Rules API prerender option, web developers can insert JSON instructions onto their pages to inform the browser about which URLs to prerender:

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

Or by document rules (available from Chrome 121), which prerenders links found in the document based on href selectors (based on the URL Pattern API ) or CSS selectors:

<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>

The Chrome team have prepared a Speculation Rules Codelab which will walk you through adding Speculation Rules to a site.

Eagerness

Browser Support

  • Chrome: 121.
  • Edge: 121.
  • Firefox: not supported.
  • Safari: not supported.

An eagerness setting is used to indicate when the speculations should fire, which is particularly useful for document rules:

  • immediate : This is used to speculate as soon as possible, that is, as soon as the speculation rules are observed.
  • eager : This behaves identically to the immediate setting, but in future, we are looking to place this somewhere between immediate and moderate .
  • moderate : This performs speculations if you hold the pointer over a link for 200 milliseconds (or on the pointerdown event if that is sooner, and on mobile where there is no hover event).
  • conservative : This speculates on pointer or touch down.

The default eagerness for list rules is immediate . The moderate and conservative options can be used to limit list rules to URLs that a user interacts with to a specific list. Though in many cases, document rules with an appropriate where condition may be more appropriate.

The default eagerness for document rules is conservative . Given a document can consist of many URLs, use of immediate or eager for document rules should be used with caution (see also the Chrome limits section next).

Which eagerness setting to use depends on your site. For a lightweight, static site, speculating more eagerly may have little cost and be beneficial for users. Sites with more complex architectures and heavier page payloads may prefer to reduce waste by speculating less often until you get more positive signal of intent from users to limit waste.

The moderate option is a middle ground, and many sites could benefit from the following speculation rule that would prerender a link when holding the pointer over the link for 200 milliseconds or on the pointerdown event as a basic—yet powerful—implementation of speculation rules:

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

Prefetch

Speculation rules can also be used to just prefetch pages, without a full prerender. This can often be a good first step on the road to prerendering:

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

Chrome limits

Chrome has limits in place to prevent overuse of the Speculation Rules API:

рвение Prefetch Prerender
immediate / eager 50 10
moderate / conservative 2 (FIFO) 2 (FIFO)
Speculation limits in Chrome.

The moderate and conservative settings—which depend on user interaction—work in a First In, First Out (FIFO) manner : after reaching the limit, a new speculation will cause the oldest speculation to be canceled and replaced by the newer one to conserve memory . A canceled speculation can be triggered again—for example by hovering over that link again—which will result in that URL being re-speculated, pushing out the oldest speculation. In this case the previous speculation will have cached any cacheable resources in the HTTP Cache for that URL so speculationing a further time should have a reduced cost. This is why the limit is set to the modest threshold of 2. Static list rules are not triggered by a user action and so have a higher limit as it is not possible for the browser to know which are needed and when they are needed.

The immediate and eager limits are also dynamic, so removing a list URL script element will create capacity by canceling those removed speculations.

Chrome will also prevent speculations being used in certain conditions including:

  • Save-Data .
  • Energy saver when enabled and on low battery.
  • Memory constraints.
  • When the "Preload pages" setting is turned off (which is also explicitly turned off by Chrome extensions such as uBlock Origin).
  • Pages opened in background tabs.

Chrome also does not render cross-origin iframes on prerendered pages until activation.

All of these conditions aim to reduce the impact of over-speculation when it would be detrimental to users.

How to include speculation rules on a page

Speculation rules can be statically included in the page's HTML or dynamically inserted into the page by JavaScript:

  • Statically included speculation rules : For example a news media site, or a blog may prerender the newest article, if that is often the next navigation for a large proportion of users, Alternatively, document rules with a moderate or conservative can be used to speculate as users interact with links.
  • Dynamically inserted speculation rules : This could be based on application logic, personalized to the user, or based on other heuristics.

Those favoring dynamic insertion based on actions such as hovering over, or clicking down on a link—as many libraries have done in the past with <link rel=prefetch> —are recommended to look at document rules, as these allow the browser to handle many of your use cases.

Speculation rules can be added in either the <head> or the <body> of in the main frame. Speculation rules in subframes are not acted upon, and speculation rules in prerendered pages are only acted upon once that page is activated.

The Speculation-Rules HTTP header

Browser Support

  • Chrome: 121.
  • Edge: 121.
  • Firefox: not supported.
  • Safari: not supported.

Источник

Speculation rules can also be delivered by using a Speculation-Rules HTTP header, rather than including them directly in the document's HTML. This allows easier deployment by CDNs without the need to alter document contents themselves.

The Speculation-Rules HTTP header is returned with the document, and points to a location of a JSON file containing the speculation rules:

Speculation-Rules: "/speculationrules.json"

This resource must use the correct MIME type and, if it is a cross-origin resource, pass a CORS check.

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

If you want to use relative URLs you may want to include the "relative_to": "document" key in your speculation rules. Otherwise, relative URLs will be relative to the speculation rules JSON file's URL. This may be particularly useful if you need to select some—or all—same-origin links.

Speculation rules and SPAs

Speculation rules are only supported for full page navigations managed by the browser, and not for Single Page Apps (SPA) or app shell pages. These architecture don't use document fetches, but instead make API or partial fetches of data or pages—which are then processed and presented in the current page. The data needed for these so called "soft navigations" can be prefetched by the app outside of speculation rules, but they cannot be prerendered.

Speculation Rules can be used to prerender the application itself from a previous page. This can help offset some of the extra initial load costs some SPAs have. However, route changes within the app cannot be prerendered.

Debug speculation rules

See the dedicated post on debugging speculation rules , for new Chrome DevTools features to assist with viewing and debugging this new API.

Multiple speculation rules

Multiple speculation rules can also be added to the same page, and they append to the existing rules. Therefore, the following different ways all result in both one.html and two.html prerendering:

List of URLs:

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

Multiple speculationrules scripts:

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

Multiple lists within one set of speculationrules

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

Browser Support

  • Chrome: 121.
  • Edge: 121.
  • Firefox: not supported.
  • Safari: not supported.

Источник

When prefetching or prerendering a page, certain URL parameters (technically known as search parameters ) may be unimportant to the page actually delivered by the server, and only used by client side JavaScript.

For example, UTM parameters are used by Google Analytics for campaign measurement, but usually don't result in different pages being delivered from the server. This means that page1.html?utm_content=123 and page1.html?utm_content=456 will deliver the same page from the server, so the same page can be reused from the cache.

Similarly, applications may use other URL parameters that are only handled client side.

The No-Vary-Search proposal allows a server to specify parameters that don't result in a difference to the resource delivered, and therefore allow a browser to reuse previously cached versions of a document which only differ by these parameters. This is supported in Chrome (and Chromium-based browsers) for prefetch navigation speculations (though we are looking to support this for prerender too ).

Speculation rules support using expects_no_vary_search to indicate where a No-Vary-Search HTTP header is expected to be returned. Doing so can help further avoid unnecessary downloads.

<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>

In this example, the /products initial page HTML is the same for both product IDs 123 and 124 . However, the page contents eventually differ based on client-side rendering using JavaScript to fetch product data using the id search parameter. So we prefetch that URL eagerly and it should return a No-Vary-Search HTTP header showing the page can be used for any id search param.

However, if the user clicks on any of the links before the prefetch has completed, the browser may not have received the /products page. In this case, the browser does not know if it will contain the No-Vary-Search HTTP header. The browser is then left with a choice of whether to fetch the link again, or wait for the prefetch to complete to see if it contains a No-Vary-Search HTTP header. The expects_no_vary_search setting allows the browser to know the page response is expected to contain a No-Vary-Search HTTP header, and to wait for that prefetch to complete.

Speculation rules restrictions and future enhancements

Speculation rules are restricted to pages opened within the same tab, but we are working to reduce that restriction .

By default speculations are restricted to same-origin pages. Speculation same-site cross-origin pages (for example, https://a.example.com could prerender a page on https://b.example.com ). To use this the speculated page ( https://b.example.com in this example) needs to opt-in by including a Supports-Loading-Mode: credentialed-prerender HTTP header or Chrome will cancel the speculation.

Future versions may also allow prerender for non-same-site, cross-origin pages as long as cookies don't exist for the prerendered page and the prerendered page opts in with a similar Supports-Loading-Mode: uncredentialed-prerender HTTP header.

Speculation rules do already support cross-origin prefetches, but again only when cookies for the cross-origin domain don't exist. If cookies exist from the user having visited that site before, then the speculation won't be triggered and will show a failure in DevTools.

Given those current limitations, one pattern that can improve your users experiences for both internal links and external links where possible is to prerender same-origin URLs and attempt to prefetch cross-origin URLs:

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

The restriction to prevent cross-origin speculations for cross-origin links by default is necessary for security. It is an improvement over <link rel="prefetch"> for cross-origin destinations which will also not send cookies but still attempt the prefetch—which will be either result in a wasted prefetch that needs to be resent or, worse still, the incorrect page loading.

Speculation rules are not supported for prefetch for pages controlled by service workers. We are working to add this support. Follow this Support service worker issue for updates. Prerender is supported for service worker-controlled pages.

Detect Speculation Rules API support

You can feature detect Speculation Rules API support with standard HTML checks:

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

Add speculation rules dynamically through JavaScript

This is an example of adding a prerender speculation rule with 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);
}

You can view a demo of Speculation Rules API prerendering, using JavaScript insertion, on this prerender demo page .

Inserting a <script type = "speculationrules"> element directly into the DOM using innerHTML won't register the speculation rules for security reasons and this must be added as shown previously. However content inserted dynamically using innerHTML which contains new links, will be picked up by existing rules on the page.

Similarly, direct editing the Elements panel in Chrome DevTools to add the <script type = "speculationrules"> element does not register the speculation rules and instead the script to dynamically add this to the DOM must be run from the Console to insert the rules.

Add speculation rules through a tag manager

To add speculation rules using a tag manager like Google Tag Manager (GTM) requires these to be inserted through JavaScript, rather than adding the <script type = "speculationrules"> element though GTM directly for the same reasons as mentioned previously:

Custom HTML tag config in Google Tag Manager
Adding Speculation Rules through Google Tag Manager.

Note this example uses var as GTM does not support const .

Cancel speculation rules

Removing speculation rules will result in the prerender being cancelled but, by the time this has happened, resources will likely have already been spent to initiate the prerender, so it is recommended not to prerender if there is a likelihood of needing to cancel the prerender.

Speculation rules and Content Security Policy

As speculation rules use a <script> element, even though they only contain JSON, they need to be included in the script-src Content-Security-Policy if the site uses this—either using a hash or nonce.

A new inline-speculation-rules can be added to script-src allowing <script type="speculationrules"> elements injected from hash or nonced scripts to be supported. This does not support rules included in the initial HTML so rules need to be injected by JavaScript for sites that use a strict CSP.

Detect and disable prerendering

Prerender is usually a positive experience for users as it allows fast page rendering—often instant. This benefits both the user, and the site owner, since prerendered pages allow a better user experience that may be difficult to achieve otherwise.

However, there may be instances when you don't want prerendering of pages to happen , for example when pages change state—either based on the initial request, or based on JavaScript executing on the page.

Enable and disable prerender in Chrome

Prerender is only enabled for those Chrome users with the "Preload pages" setting in chrome://settings/performance/ . Additionally, prerender is also disabled on low-memory devices, or if the operating system is in Save-data or Energy saver modes. See the Chrome limits section.

Detect and disable prerender server-side

Prerendered pages will be sent with the Sec-Purpose HTTP header:

Sec-Purpose: prefetch;prerender

Prefetched pages using the Speculation Rules API will have this header set to just prefetch :

Sec-Purpose: prefetch

Servers can respond based on this header, to log speculation requests, return different content, or prevent a prerender from happening. If a non-success response code is returned—that is, not in the 200-299 range after redirects—then the page won't be prerendered and any prefetch page will be discarded. Note also that 204 and 205 responses are additional not valid for prerendering , but are valid for prefetch.

If you don't want a particular page to be prerendered, returning a non-2XX response code (such as 503) is the best way to ensure it won't happen. However, to deliver the best experience, it is recommended to instead allow prerendering, but delay any actions that should only happen then the page is actually viewed, using JavaScript.

Detect prerender in JavaScript

The document.prerendering API will return true while the page is prerendering. This can be used by pages to prevent—or delay—certain activities during the prerender until the page is actually activated.

Once a prerendered document is activated, PerformanceNavigationTiming 's activationStart will also be set to a non-zero time representing the time between when the prerender was started and the document was actually activated.

You can have a function to check for prerendering and prerendered pages like the following:

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

The easiest way to see if a page was prerendered (either in full or partially) is to open DevTools after the page is activated and type performance.getEntriesByType('navigation')[0].activationStart in the console. If a non-zero value is returned, you know the page was prerendered:

Console in Chrome DevTools showing a positive activationStart indicating the page was prerendered
Testing prerender in the console.

When the page is activated by the user viewing the page, the prerenderingchange event will be dispatched on the document , which can then be used to enable activities that previously would be started by default on page load but which you want to delay until the page is actually viewed by the user.

Using these APIs, frontend JavaScript can detect and act upon prerendered pages appropriately.

Impact on analytics

Analytics are used to measure website usage, for example using Google Analytics to measure page views, and events. Or by measuring performance metrics of pages using Real User Monitoring (RUM) .

Pages should only be prerendered when there is a high probability the page will be loaded by the user. This is why the Chrome address bar prerendering options only happen when there is such a high probability (greater than 80% of the time).

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.

Measure performance

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.

Acknowledgements

Thumbnail image by Marc-Olivier Jodoin on Unsplash

,

Browser Support

  • Chrome: 109.
  • Edge: 109.
  • Firefox: not supported.
  • Safari: not supported.

The Chrome team has brought back full prerendering of future pages that a user is likely to navigate to.

A brief history of prerender

In the past, Chrome supported the <link rel="prerender" href="/next-page"> resource hint, however it was not broadly supported beyond Chrome, and it wasn't a very expressive API.

This legacy prerendering using the link rel=prerender hint was deprecated in favor of NoState Prefetch , which instead fetched the resources needed by the future page, but did not fully prerender the page nor execute JavaScript. NoState Prefetch does help improve page performance by improving the resource loading, but won't deliver an instant page load like a full prerender would.

The Chrome team has now reintroduced full prerendering back into Chrome. To avoid complications with existing usage, and to allow for future expansion of prerendering, this new prerender mechanism won't use the <link rel="prerender"...> syntax, which remains in place for NoState Prefetch, with a view of retiring this at some point in the future.

How is a page prerendered?

A page can be prerendered in one of four ways, all of which aim to make navigations quicker:

  1. When you type a URL into the Chrome address bar (also known as "the omnibox"), Chrome may automatically prerender the page for you, if it has high confidence you will visit that page, based on your previous browsing history.
  2. When you use the bookmarks bar, Chrome may automatically prerender the page for you on holding the pointer over one of the bookmark buttons.
  3. When you type a search term into the Chrome address bar, Chrome may automatically prerender the search results page, when instructed to do so by the search engine.
  4. Sites can use the Speculation Rules API , to programmatically tell Chrome which pages to prerender. This replaces what <link rel="prerender"...> used to do and allows sites to proactively prerender a page based on speculation rules on the page. These can statically exist on the pages, or be dynamically injected by JavaScript as the page owner sees fit.

In each of these cases, a prerender behaves as if the page has been opened in an invisible background tab, and then is "activated" by replacing the foreground tab with that prerendered page. If a page is activated before it has fully prerendered, then its current state is "foregrounded" and continues to load, which means you can still get a good head start.

As the prerendered page is opened in a hidden state, a number of APIs that cause intrusive behaviors (for example, prompts) are not activated in this state, and are instead delayed until the page is activated. In the small number of cases where this is not yet possible, the prerender is canceled. The Chrome team is working on exposing prerender cancellation reasons as an API, and also enhancing DevTools capabilities to make identifying such edge cases easier.

Impact of prerendering

Prerendering allows a near-instant page load as shown in the following video:

Example impact of prerendering.

The example site is already a fast site, but even with this you can see how prerendering improves the user experience. This can therefore also have a direct impact on a site's Core Web Vitals , with near zero LCP, reduced CLS (since any load CLS happens before the initial view), and improved INP (since the load should be completed before the user interacts).

Even when a page activates before it is fully loaded, having a head start to the page load, should improve the loading experience. When a link is activated while prerendering is still happening, the prerendering page will move to the main frame and continue loading.

However, prerendering does use additional memory and network bandwidth. Be careful not to over-prerender, at a cost of user resources. Only prerender when there is a high likelihood of the page being navigated to.

See the Measuring performance section for more information on how to measure the actual performance impact in your analytics.

View Chrome's address bar predictions

For the first use case, you can view Chrome's predictions for URLs in the chrome://predictors page:

The Chrome Predictors page filtered to show low (grey), medium (amber), and high (green) predictions based on text entered.
Chrome Predictors page.

Green lines indicate enough confidence to trigger prerendering. In this example typing "s" gives a reasonable confidence (amber), but once you type "sh" then Chrome has enough confidence that you nearly always navigate to https://sheets.google.com .

This screenshot was taken in a relatively fresh Chrome install, and filtering out zero confidence predictions, but if you view your own predictors you will likely see considerably more entries, and potentially more characters required to reach a high enough confidence level.

These predictors are also what drive the address bar suggested options you may have noticed:

The Chrome address bar 'Typeahead' feature
Address bar 'Typeahead' feature.

Chrome will continually update its predictors based on your typing and selections.

  • For a greater than 50% confidence level (shown in amber), Chrome proactively preconnects to the domain, but does not prerender the page.
  • For a greater than 80% confidence level (shown in green), Chrome will prerender the URL.

The Speculation Rules API

For the Speculation Rules API prerender option, web developers can insert JSON instructions onto their pages to inform the browser about which URLs to prerender:

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

Or by document rules (available from Chrome 121), which prerenders links found in the document based on href selectors (based on the URL Pattern API ) or CSS selectors:

<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>

The Chrome team have prepared a Speculation Rules Codelab which will walk you through adding Speculation Rules to a site.

Eagerness

Browser Support

  • Chrome: 121.
  • Edge: 121.
  • Firefox: not supported.
  • Safari: not supported.

An eagerness setting is used to indicate when the speculations should fire, which is particularly useful for document rules:

  • immediate : This is used to speculate as soon as possible, that is, as soon as the speculation rules are observed.
  • eager : This behaves identically to the immediate setting, but in future, we are looking to place this somewhere between immediate and moderate .
  • moderate : This performs speculations if you hold the pointer over a link for 200 milliseconds (or on the pointerdown event if that is sooner, and on mobile where there is no hover event).
  • conservative : This speculates on pointer or touch down.

The default eagerness for list rules is immediate . The moderate and conservative options can be used to limit list rules to URLs that a user interacts with to a specific list. Though in many cases, document rules with an appropriate where condition may be more appropriate.

The default eagerness for document rules is conservative . Given a document can consist of many URLs, use of immediate or eager for document rules should be used with caution (see also the Chrome limits section next).

Which eagerness setting to use depends on your site. For a lightweight, static site, speculating more eagerly may have little cost and be beneficial for users. Sites with more complex architectures and heavier page payloads may prefer to reduce waste by speculating less often until you get more positive signal of intent from users to limit waste.

The moderate option is a middle ground, and many sites could benefit from the following speculation rule that would prerender a link when holding the pointer over the link for 200 milliseconds or on the pointerdown event as a basic—yet powerful—implementation of speculation rules:

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

Prefetch

Speculation rules can also be used to just prefetch pages, without a full prerender. This can often be a good first step on the road to prerendering:

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

Chrome limits

Chrome has limits in place to prevent overuse of the Speculation Rules API:

рвение Prefetch Prerender
immediate / eager 50 10
moderate / conservative 2 (FIFO) 2 (FIFO)
Speculation limits in Chrome.

The moderate and conservative settings—which depend on user interaction—work in a First In, First Out (FIFO) manner : after reaching the limit, a new speculation will cause the oldest speculation to be canceled and replaced by the newer one to conserve memory . A canceled speculation can be triggered again—for example by hovering over that link again—which will result in that URL being re-speculated, pushing out the oldest speculation. In this case the previous speculation will have cached any cacheable resources in the HTTP Cache for that URL so speculationing a further time should have a reduced cost. This is why the limit is set to the modest threshold of 2. Static list rules are not triggered by a user action and so have a higher limit as it is not possible for the browser to know which are needed and when they are needed.

The immediate and eager limits are also dynamic, so removing a list URL script element will create capacity by canceling those removed speculations.

Chrome will also prevent speculations being used in certain conditions including:

  • Save-Data .
  • Energy saver when enabled and on low battery.
  • Memory constraints.
  • When the "Preload pages" setting is turned off (which is also explicitly turned off by Chrome extensions such as uBlock Origin).
  • Pages opened in background tabs.

Chrome also does not render cross-origin iframes on prerendered pages until activation.

All of these conditions aim to reduce the impact of over-speculation when it would be detrimental to users.

How to include speculation rules on a page

Speculation rules can be statically included in the page's HTML or dynamically inserted into the page by JavaScript:

  • Statically included speculation rules : For example a news media site, or a blog may prerender the newest article, if that is often the next navigation for a large proportion of users, Alternatively, document rules with a moderate or conservative can be used to speculate as users interact with links.
  • Dynamically inserted speculation rules : This could be based on application logic, personalized to the user, or based on other heuristics.

Those favoring dynamic insertion based on actions such as hovering over, or clicking down on a link—as many libraries have done in the past with <link rel=prefetch> —are recommended to look at document rules, as these allow the browser to handle many of your use cases.

Speculation rules can be added in either the <head> or the <body> of in the main frame. Speculation rules in subframes are not acted upon, and speculation rules in prerendered pages are only acted upon once that page is activated.

The Speculation-Rules HTTP header

Browser Support

  • Chrome: 121.
  • Edge: 121.
  • Firefox: not supported.
  • Safari: not supported.

Источник

Speculation rules can also be delivered by using a Speculation-Rules HTTP header, rather than including them directly in the document's HTML. This allows easier deployment by CDNs without the need to alter document contents themselves.

The Speculation-Rules HTTP header is returned with the document, and points to a location of a JSON file containing the speculation rules:

Speculation-Rules: "/speculationrules.json"

This resource must use the correct MIME type and, if it is a cross-origin resource, pass a CORS check.

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

If you want to use relative URLs you may want to include the "relative_to": "document" key in your speculation rules. Otherwise, relative URLs will be relative to the speculation rules JSON file's URL. This may be particularly useful if you need to select some—or all—same-origin links.

Speculation rules and SPAs

Speculation rules are only supported for full page navigations managed by the browser, and not for Single Page Apps (SPA) or app shell pages. These architecture don't use document fetches, but instead make API or partial fetches of data or pages—which are then processed and presented in the current page. The data needed for these so called "soft navigations" can be prefetched by the app outside of speculation rules, but they cannot be prerendered.

Speculation Rules can be used to prerender the application itself from a previous page. This can help offset some of the extra initial load costs some SPAs have. However, route changes within the app cannot be prerendered.

Debug speculation rules

See the dedicated post on debugging speculation rules , for new Chrome DevTools features to assist with viewing and debugging this new API.

Multiple speculation rules

Multiple speculation rules can also be added to the same page, and they append to the existing rules. Therefore, the following different ways all result in both one.html and two.html prerendering:

List of URLs:

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

Multiple speculationrules scripts:

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

Multiple lists within one set of speculationrules

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

Browser Support

  • Chrome: 121.
  • Edge: 121.
  • Firefox: not supported.
  • Safari: not supported.

Источник

When prefetching or prerendering a page, certain URL parameters (technically known as search parameters ) may be unimportant to the page actually delivered by the server, and only used by client side JavaScript.

For example, UTM parameters are used by Google Analytics for campaign measurement, but usually don't result in different pages being delivered from the server. This means that page1.html?utm_content=123 and page1.html?utm_content=456 will deliver the same page from the server, so the same page can be reused from the cache.

Similarly, applications may use other URL parameters that are only handled client side.

The No-Vary-Search proposal allows a server to specify parameters that don't result in a difference to the resource delivered, and therefore allow a browser to reuse previously cached versions of a document which only differ by these parameters. This is supported in Chrome (and Chromium-based browsers) for prefetch navigation speculations (though we are looking to support this for prerender too ).

Speculation rules support using expects_no_vary_search to indicate where a No-Vary-Search HTTP header is expected to be returned. Doing so can help further avoid unnecessary downloads.

<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>

In this example, the /products initial page HTML is the same for both product IDs 123 and 124 . However, the page contents eventually differ based on client-side rendering using JavaScript to fetch product data using the id search parameter. So we prefetch that URL eagerly and it should return a No-Vary-Search HTTP header showing the page can be used for any id search param.

However, if the user clicks on any of the links before the prefetch has completed, the browser may not have received the /products page. In this case, the browser does not know if it will contain the No-Vary-Search HTTP header. The browser is then left with a choice of whether to fetch the link again, or wait for the prefetch to complete to see if it contains a No-Vary-Search HTTP header. The expects_no_vary_search setting allows the browser to know the page response is expected to contain a No-Vary-Search HTTP header, and to wait for that prefetch to complete.

Speculation rules restrictions and future enhancements

Speculation rules are restricted to pages opened within the same tab, but we are working to reduce that restriction .

By default speculations are restricted to same-origin pages. Speculation same-site cross-origin pages (for example, https://a.example.com could prerender a page on https://b.example.com ). To use this the speculated page ( https://b.example.com in this example) needs to opt-in by including a Supports-Loading-Mode: credentialed-prerender HTTP header or Chrome will cancel the speculation.

Future versions may also allow prerender for non-same-site, cross-origin pages as long as cookies don't exist for the prerendered page and the prerendered page opts in with a similar Supports-Loading-Mode: uncredentialed-prerender HTTP header.

Speculation rules do already support cross-origin prefetches, but again only when cookies for the cross-origin domain don't exist. If cookies exist from the user having visited that site before, then the speculation won't be triggered and will show a failure in DevTools.

Given those current limitations, one pattern that can improve your users experiences for both internal links and external links where possible is to prerender same-origin URLs and attempt to prefetch cross-origin URLs:

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

The restriction to prevent cross-origin speculations for cross-origin links by default is necessary for security. It is an improvement over <link rel="prefetch"> for cross-origin destinations which will also not send cookies but still attempt the prefetch—which will be either result in a wasted prefetch that needs to be resent or, worse still, the incorrect page loading.

Speculation rules are not supported for prefetch for pages controlled by service workers. We are working to add this support. Follow this Support service worker issue for updates. Prerender is supported for service worker-controlled pages.

Detect Speculation Rules API support

You can feature detect Speculation Rules API support with standard HTML checks:

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

Add speculation rules dynamically through JavaScript

This is an example of adding a prerender speculation rule with 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);
}

You can view a demo of Speculation Rules API prerendering, using JavaScript insertion, on this prerender demo page .

Inserting a <script type = "speculationrules"> element directly into the DOM using innerHTML won't register the speculation rules for security reasons and this must be added as shown previously. However content inserted dynamically using innerHTML which contains new links, will be picked up by existing rules on the page.

Similarly, direct editing the Elements panel in Chrome DevTools to add the <script type = "speculationrules"> element does not register the speculation rules and instead the script to dynamically add this to the DOM must be run from the Console to insert the rules.

Add speculation rules through a tag manager

To add speculation rules using a tag manager like Google Tag Manager (GTM) requires these to be inserted through JavaScript, rather than adding the <script type = "speculationrules"> element though GTM directly for the same reasons as mentioned previously:

Custom HTML tag config in Google Tag Manager
Adding Speculation Rules through Google Tag Manager.

Note this example uses var as GTM does not support const .

Cancel speculation rules

Removing speculation rules will result in the prerender being cancelled but, by the time this has happened, resources will likely have already been spent to initiate the prerender, so it is recommended not to prerender if there is a likelihood of needing to cancel the prerender.

Speculation rules and Content Security Policy

As speculation rules use a <script> element, even though they only contain JSON, they need to be included in the script-src Content-Security-Policy if the site uses this—either using a hash or nonce.

A new inline-speculation-rules can be added to script-src allowing <script type="speculationrules"> elements injected from hash or nonced scripts to be supported. This does not support rules included in the initial HTML so rules need to be injected by JavaScript for sites that use a strict CSP.

Detect and disable prerendering

Prerender is usually a positive experience for users as it allows fast page rendering—often instant. This benefits both the user, and the site owner, since prerendered pages allow a better user experience that may be difficult to achieve otherwise.

However, there may be instances when you don't want prerendering of pages to happen , for example when pages change state—either based on the initial request, or based on JavaScript executing on the page.

Enable and disable prerender in Chrome

Prerender is only enabled for those Chrome users with the "Preload pages" setting in chrome://settings/performance/ . Additionally, prerender is also disabled on low-memory devices, or if the operating system is in Save-data or Energy saver modes. See the Chrome limits section.

Detect and disable prerender server-side

Prerendered pages will be sent with the Sec-Purpose HTTP header:

Sec-Purpose: prefetch;prerender

Prefetched pages using the Speculation Rules API will have this header set to just prefetch :

Sec-Purpose: prefetch

Servers can respond based on this header, to log speculation requests, return different content, or prevent a prerender from happening. If a non-success response code is returned—that is, not in the 200-299 range after redirects—then the page won't be prerendered and any prefetch page will be discarded. Note also that 204 and 205 responses are additional not valid for prerendering , but are valid for prefetch.

If you don't want a particular page to be prerendered, returning a non-2XX response code (such as 503) is the best way to ensure it won't happen. However, to deliver the best experience, it is recommended to instead allow prerendering, but delay any actions that should only happen then the page is actually viewed, using JavaScript.

Detect prerender in JavaScript

The document.prerendering API will return true while the page is prerendering. This can be used by pages to prevent—or delay—certain activities during the prerender until the page is actually activated.

Once a prerendered document is activated, PerformanceNavigationTiming 's activationStart will also be set to a non-zero time representing the time between when the prerender was started and the document was actually activated.

You can have a function to check for prerendering and prerendered pages like the following:

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

The easiest way to see if a page was prerendered (either in full or partially) is to open DevTools after the page is activated and type performance.getEntriesByType('navigation')[0].activationStart in the console. If a non-zero value is returned, you know the page was prerendered:

Console in Chrome DevTools showing a positive activationStart indicating the page was prerendered
Testing prerender in the console.

When the page is activated by the user viewing the page, the prerenderingchange event will be dispatched on the document , which can then be used to enable activities that previously would be started by default on page load but which you want to delay until the page is actually viewed by the user.

Using these APIs, frontend JavaScript can detect and act upon prerendered pages appropriately.

Impact on analytics

Analytics are used to measure website usage, for example using Google Analytics to measure page views, and events. Or by measuring performance metrics of pages using Real User Monitoring (RUM) .

Pages should only be prerendered when there is a high probability the page will be loaded by the user. This is why the Chrome address bar prerendering options only happen when there is such a high probability (greater than 80% of the time).

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.

Measure performance

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.

Acknowledgements

Thumbnail image by Marc-Olivier Jodoin on Unsplash