API правил спекулятивного загрузки
Экспериментально: Это экспериментальная технология.
Внимательно ознакомьтесь со таблицей совместимости с браузерами, прежде чем использовать её в производстве.
API правил спекулятивной загрузки предназначен для повышения производительности при будущих переходах. Он нацелен на URL документов, а не на конкретные файлы ресурсов, поэтому подходит для многостраничных приложений (MPA), а не для одностраничных (SPA).
API правил спекулятивной загрузки предлагает альтернативу широко используемой функции <link rel="prefetch"> и призван заменить устаревшую функцию, доступную только в Chrome, <link rel="prerender">. Он предоставляет множество улучшений по сравнению с этими технологиями, а также более выразительный и настраиваемый синтаксис для указания, какие документы следует предзагружать или предварительно рендерить.
Примечание: API правил спекулятивной загрузки не обрабатывает предзагрузку подресурсов; для этого вам необходимо использовать <link rel="prefetch">.
Концепции и использование
Правила спекулятивной загрузки можно указать внутри встроенных <script type="speculationrules"> элементов и внешних текстовых файлов, на которые ссылается заголовок ответа Speculation-Rules. Правила задаются в формате JSON.
Пример скрипта:
<script type="speculationrules">
{
"prerender": [
{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": { "href_matches": "/logout" } },
{ "not": { "href_matches": "/*\\?*(^|&)add-to-cart=*" } },
{ "not": { "selector_matches": ".no-prerender" } },
{ "not": { "selector_matches": "[rel~=nofollow]" } }
]
}
}
],
"prefetch": [
{
"urls": ["next.html", "next2.html"],
"requires": ["anonymous-client-ip-when-cross-origin"],
"referrer_policy": "no-referrer"
}
]
}
</script>
Правила спекулятивной загрузки, использующие элемент <script> , необходимо явно разрешить в директиве Content-Security-Policy script-src, если сайт её использует. Это делается путем добавления одного из 'inline-speculation-rules' источников, источника на основе хэша или источника с нонсом.
Пример HTTP-заголовка:
Speculation-Rules: "/rules/prefetch.json"
Текстовый ресурс, содержащий JSON-правила, может иметь любое допустимое имя и расширение, но должен быть передан с типом MIME application/speculationrules+json.
Примечание: Правила могут быть указаны как в встроенном скрипте, так и в HTTP-заголовке одновременно — все примененные к документу правила анализируются и добавляются в список правил спекулятивной загрузки документа.
Для каждого типа спекулятивной загрузки (например, "prerender" или "prefetch" ) вы указываете отдельный массив, содержащий правила. Каждое правило содержится в объекте, который, например, определяет список ресурсов для загрузки, а также параметры, такие как явное значение Referrer-Policy для каждого правила. Обратите внимание, что предварительно отрисованные URL также предзагружаются.
Полное объяснение доступного синтаксиса см. в <script type="speculationrules">.
Использование предзагрузки
Включение prefetch правил внутри <script type="speculationrules"> элемента или Speculation-Rules заголовка заставит поддерживающие браузеры загрузить тело ответа указанных страниц, но не какие-либо подресурсы, на которые ссылается страница. При переходе на предварительно загруженную страницу она будет отображаться намного быстрее, чем если бы она не была предзагружена.
Результаты хранятся в кэше в памяти на странице. Все предварительно загруженные страницы удаляются из кэша при переходе на другую страницу, за исключением, конечно, предварительно загруженного документа, на который вы затем переходите.
Это означает, что если вы предзагружаете что-то, на что пользователь не переходит, это обычно расточительство ресурсов, хотя результат может быть добавлен в кэш HTTP, если это разрешено заголовками. Тем не менее, первоначальные затраты на предзагрузку намного меньше, чем первоначальные затраты на предварительное рендерирование, поэтому рекомендуется широко применять предзагрузку, например, предзагружать все важные страницы на вашем сайте, если они безопасны для предзагрузки (подробнее см. Небезопасные условия спекулятивной загрузки).
Предзагрузки с одного и разных сайтов будут работать, но предзагрузки с разных сайтов ограничены (см. различия между «одним сайтом» и «разными сайтами»). По соображениям безопасности предзагрузки с разных сайтов в настоящее время будут работать только в том случае, если у пользователя нет cookie для целевого сайта — мы не хотим, чтобы сайты отслеживали активность пользователя по предварительно загруженным страницам (которые он может даже не посетить) на основе ранее установленных cookie.
Примечание: В будущем для предзагрузки с разных сайтов будет предоставлен опциональный режим через заголовок Supports-Loading-Mode, но на момент написания он не был реализован (доступен только опциональный режим предварительного рендеринга с одного сайта).
Для браузеров, которые его поддерживают, предзагрузка с помощью правил спекулятивной загрузки предпочтительнее более старых механизмов предзагрузки, а именно <link rel="prefetch"> и fetch() с опцией priority: "low" . Поскольку известно, что предзагрузка с помощью правил спекулятивной загрузки предназначена для переходов, а не для общей предзагрузки ресурсов:
- Она может использоваться для переходов с разных сайтов, тогда как
<link rel="prefetch">не может. - Она не блокируется заголовками
Cache-Control, тогда как<link rel="prefetch">часто блокируется.
Кроме того, предзагрузка с помощью правил спекулятивной загрузки:
- Автоматически снижает приоритет при необходимости (
fetch()нет). - Учитывает настройки пользователя. Например, предзагрузка не происходит, когда устройство пользователя находится в режиме экономии заряда батареи или мобильного трафика.
- Хранит предзагруженные ресурсы в кэше в памяти на странице, а не в кэше HTTP, что может привести к немного более быстрой предзагрузке.
Использование предварительного рендеринга
Включение prerender правил внутри <script type="speculationrules"> элемента или Speculation-Rules заголовка заставит поддерживающие браузеры загрузить, отрисовать и загрузить содержимое в невидимую вкладку, хранящуюся в кэше в памяти на странице. Это включает загрузку всех подресурсов, выполнение всего JavaScript-кода, а также загрузку подресурсов и выполнение операций запроса данных, начатых JavaScript-кодом. Любые кэшированные предварительные рендеринги и их подресурсы удаляются при переходе на другую страницу, за исключением, конечно, предварительно отрисованного документа, на который вы затем переходите.
Будущие переходы на предварительно отрисованную страницу будут практически мгновенными. Браузер активирует невидимую вкладку вместо выполнения обычного процесса перехода, заменяя старую переднюю страницу предварительно отрисованной страницей. Если страница активируется до ее полного предварительного рендеринга, она активируется в своем текущем состоянии и продолжает загружаться, что означает, что вы все равно увидите существенное улучшение производительности.
Предварительный рендеринг использует память и пропускную способность сети. Если вы предварительно рендерите что-то, на что пользователь не переходит, это будет расточительство (хотя результат может попасть в кэш HTTP, если это разрешено заголовками, и может быть использован позднее). Первоначальные затраты на предварительный рендеринг значительно выше, чем первоначальные затраты на предзагрузку, а также могут существовать другие условия, делающие содержимое небезопасным для предварительного рендеринга (подробнее см. Небезопасные условия спекулятивной загрузки). В результате рекомендуется использовать предварительный рендеринг более экономно, тщательно рассматривая случаи, когда существует высокая вероятность перехода на страницу, и вы считаете, что выгода для пользователя стоит дополнительных затрат.
Примечание: Для оценки возможных потерь ресурсов, предварительный рендеринг использует примерно столько же ресурсов, сколько и рендеринг <iframe>.
Примечание: Многие API будут автоматически отложены при предварительном рендеринге или до активации. Подробнее см. Функции платформы, отложенные или ограниченные во время предварительного рендеринга.
Предварительный рендеринг по умолчанию ограничен документами одного источника. Предварительный рендеринг с разных сайтов, но одного источника, возможен — для этого целевой объект перехода должен использовать заголовок Supports-Loading-Mode со значением credentialed-prerender. Предварительный рендеринг с разных сайтов в настоящее время невозможен.
Для браузеров, которые его поддерживают, предварительный рендеринг с помощью правил спекулятивной загрузки предпочтительнее более старых механизмов предварительного рендеринга, а именно <link rel="prerender">:
-
<link rel="prerender">специфичен для Chrome и никогда не был стандартизирован, и команда инженеров Chrome в настоящее время занимается его отзывом. - Он загружает подресурсы, загруженные через JavaScript, тогда как
<link rel="prerender">нет. - Он не блокируется настройками
Cache-Control, тогда как<link rel="prerender">часто блокируется. - Предварительный рендеринг с помощью правил спекулятивной загрузки должен рассматриваться как подсказка и как постепенное улучшение. В отличие от
<link rel="prerender">, это спекулятивная подсказка, и браузер может не выполнить подсказку в зависимости от настроек пользователя, текущего использования памяти или других эвристических методов.
Обнаружение поддержки API правил спекулятивной загрузки
Вы можете проверить, поддерживается ли API правил спекулятивной загрузки, используя следующий код:
if (
HTMLScriptElement.supports &&
HTMLScriptElement.supports("speculationrules")
) {
console.log("Your browser supports the Speculation Rules API.");
}
Например, вы можете вставить правила спекулятивной загрузки для предзагрузки в поддерживающих браузерах, но использовать более старую технологию, например, <link rel="prefetch"> в других:
if (
HTMLScriptElement.supports &&
HTMLScriptElement.supports("speculationrules")
) {
const specScript = document.createElement("script");
specScript.type = "speculationrules";
const specRules = {
prefetch: [
{
source: "list",
urls: ["/next.html"],
},
],
};
specScript.textContent = JSON.stringify(specRules);
document.body.append(specScript);
} else {
const linkElem = document.createElement("link");
linkElem.rel = "prefetch";
linkElem.href = "/next.html";
document.head.append(linkElem);
}
Обнаружение предварительно загруженных и предварительно отрисованных страниц
В этом разделе рассматриваются различные способы определения того, была ли запрошенная страница предварительно загружена или предварительно отрисована.
Обнаружение на стороне сервера
Запросы к страницам, предварительно загруженные и предварительно отрисованные, отправляются с заголовком запроса Sec-Purpose:
Для предварительной загрузки:
Sec-Purpose: prefetch
Для предварительной отрисовки:
Sec-Purpose: prefetch;prerender
Серверы могут отвечать на основе этого заголовка, например, для регистрации запросов на предварительную загрузку, возврата другого содержимого или даже предотвращения предварительной загрузки. Если возвращается код ответа, отличный от успешного (любой HTTP-статус, кроме диапазона 200-299 после перенаправлений), то страница не будет предварительно загружена/отрисована. Кроме того, коды статусов 204 и 205 также предотвращают предварительную отрисовку (но не предотвращают предварительную загрузку).
Использование кода, отличного от успешного (например, 503), является самым простым способом предотвращения предварительной загрузки на стороне сервера, хотя обычно лучше разрешить предварительную загрузку/отрисовку и использовать JavaScript для задержки любых действий, которые должны выполняться только при фактическом просмотре страницы.
Обнаружение предварительной загрузки с помощью JavaScript
Когда страница предварительно загружается, её запись PerformanceResourceTiming.deliveryType вернёт значение "navigational-prefetch". Вы можете использовать следующее для выполнения функции при получении записи производительности типа "navigational-prefetch":
if (
performance.getEntriesByType("navigation")[0].deliveryType ===
"navigational-prefetch"
) {
respondToPrefetch(); // Author-defined function
}
Этот метод полезен при измерении производительности или при отложенном выполнении действий, которые могут вызвать проблемы при предварительной загрузке (см. Небезопасная предварительная загрузка).
Обнаружение предварительной отрисовки с помощью JavaScript
Для выполнения действия во время предварительной отрисовки страницы, можно проверить свойство Document.prerendering. Например, вы можете запустить некоторые аналитические данные:
if (document.prerendering) {
analytics.sendInfo("got this far during prerendering!");
}
При активации предварительно отрисованного документа PerformanceNavigationTiming.activationStart устанавливается в DOMHighResTimeStamp, представляющем время между началом предварительной отрисовки и активацией документа. Следующая функция может проверять предварительную отрисовку и предварительно отрисованные страницы:
function pagePrerendered() {
return (
document.prerendering ||
self.performance?.getEntriesByType?.("navigation")[0]?.activationStart > 0
);
}
Когда пользователь активирует предварительно отрисованную страницу, событие prerenderingchange будет срабатывать. Это можно использовать для включения действий, которые в прошлых случаях запускались по умолчанию при загрузке страницы, но которые вы хотите отложить до просмотра страницы пользователем. Следующий код устанавливает обработчик событий для выполнения функции после завершения предварительной отрисовки, на предварительно отрисованной странице или её немедленного выполнения на странице без предварительной отрисовки:
if (document.prerendering) {
document.addEventListener("prerenderingchange", initAnalytics, {
once: true,
});
} else {
initAnalytics();
}
Небезопасные условия упреждающей загрузки
Этот раздел описывает условия, при которых предварительная загрузка и/или предварительная отрисовка являются небезопасными. Это означает, что предварительная загрузка/отрисовка страниц, демонстрирующих эти условия, может потребовать мер по смягчению последствий в вашем коде или требует избегания.
Небезопасная предварительная загрузка
Как уже упоминалось, мы рекомендуем использовать предварительную загрузку широко, так как соотношение риска к выгоде довольно низкое — потенциальная трата ресурсов минимальна, а улучшения производительности могут быть значительными. Однако вы должны убедиться, что предварительно загруженные страницы не вызывают проблем с потоком вашего приложения.
При выполнении предварительной загрузки браузер загружает тело ответа указанной страницы с помощью одного запроса GET, к которому пользователь может перейти в будущем. Проблемы могут возникнуть, когда URL запроса выполняет побочный эффект на стороне сервера, которого вы не хотите, пока к URL не перейдут.
Например:
- Ссылки для выхода из системы.
- Ссылки для смены языка.
- Ссылки «Добавить в корзину».
- Ссылки для входа, где сервер отправляет SMS, например, для получения одноразового пароля (OTP).
- Ссылки, увеличивающие лимит использования пользователя, такие как использование ежемесячного лимита бесплатных статей или запуск таймера на ежемесячные минуты.
- Ссылки, инициирующие отслеживание конверсий объявлений на стороне сервера.
Эти проблемы можно смягчить на сервере, отслеживая заголовок Sec-Purpose: prefetch при поступлении запросов, а затем выполняя определённый код для отсрочки проблемных функций. Позже, когда пользователь перейдёт на страницу, вы можете инициировать отложенные функции с помощью JavaScript, если это необходимо.
Примечание: Более подробную информацию о коде обнаружения можно найти в разделе Обнаружение предварительно загруженных и предварительно отрисованных страниц.
Также потенциально небезопасно предварительно загружать документ, содержимое которого на сервере может измениться из-за действий пользователя на текущей странице. Это может включать, например, страницы со скидками или карты мест в кинотеатре. Тщательно протестируйте такие случаи и смягчите эти проблемы, обновляя содержимое после загрузки страницы. См. раздел Состояние, изменяющееся на сервере для получения более подробной информации об этих случаях.
Примечание: Браузеры кешируют предварительно загруженные страницы в течение короткого времени (например, Chrome кеширует их в течение 5 минут) перед удалением, поэтому в любом случае пользователи могут увидеть содержимое, которое устарело на 5 минут.
Предварительная загрузка безопасна, если все побочные эффекты загрузки страницы являются результатом выполнения JavaScript, так как JavaScript не будет выполняться до активации.
Ещё один совет — проверить URL, запрещённые в вашем файле robots.txt — обычно эти URL указывают на страницы, доступные только авторизованным пользователям, и поэтому не должны отображаться в результатах поиска. Многие из них будут в порядке, но это может быть хорошее место для поиска небезопасных для предварительной загрузки URL-адресов (то есть они демонстрируют условия, описанные выше).
Небезопасная предварительная отрисовка
Предварительная отрисовка является более рискованной, чем предварительная загрузка, и поэтому должна применяться экономно, в тех случаях, когда это оправдано. Существует больше небезопасных условий, требующих внимания при предварительной отрисовке, поэтому, хотя награда выше, риск слишком велик.
При выполнении предварительной отрисовки браузер GET URL, отрисовывает и загружает содержимое в невидимой вкладке. Это включает выполнение JavaScript содержимого и загрузку всех подресурсов, включая те, которые загружаются JavaScript. Содержимое может быть потенциально небезопасным для предварительной отрисовки, если наблюдаются следующие условия:
- URL является небезопасным для предварительной загрузки. Сначала ознакомьтесь с предыдущим разделом, если вы этого ещё не сделали, и поймите, что эти условия также одинаково применимы к небезопасной предварительной отрисовке.
- JavaScript страницы изменяет кэш браузера (например, Web Storage или IndexedDB) при загрузке таким образом, что может привести к путанице на других, не предварительно отрисованных страницах, которые пользователь сейчас просматривает.
- На странице выполняется JavaScript или загружаются изображения, которые вызывают побочные эффекты, такие как отправка аналитики, регистрация показов рекламы или иные изменения состояния приложения так, как будто пользователь уже взаимодействовал с ним. Опять же, это может повлиять на поток приложения или привести к неправильным отчётам о производительности или использовании. См. раздел Состояние, изменяющееся на сервере для получения более подробной информации об этих случаях.
Для смягчения этих проблем можно использовать следующие методы:
- Наблюдайте за заголовком
Sec-Purpose: prefetchна сервере по мере поступления запросов, а затем запускайте специальный код для отсрочки проблемных функций. - Используйте событие
prerenderingchangeдля обнаружения активации предварительно отрисованной страницы и выполнения кода в результате. Это полезно в двух случаях:- Отсрочка кода, который может вызвать проблемы, если он будет запущен до просмотра страницы. Например, вы можете подождать активации, чтобы обновить кэш браузера или изменить состояние на сервере с помощью JavaScript. Это может предотвратить ситуации, когда пользовательский интерфейс и состояние приложения расходятся, например, в корзине товаров отображается ноль элементов, хотя пользователь добавил некоторые.
- Если это невозможно, вы по-прежнему можете повторно запустить код после активации страницы, чтобы снова обновить приложение. Например, динамичная страница со скидками может полагаться на обновления содержимого, поступающие из сторонней библиотеки. Если вы не можете отложить обновления, вы всегда можете получить свежие обновления после просмотра страницы пользователем. Предварительно отрисованные страницы могут обновляться в реальном времени с помощью API канала трансляции Broadcast Channel API или другого механизма, такого как
fetch()илиWebSocket. Это гарантирует, что пользователь увидит актуальное содержимое после активации предварительной отрисовки.
- Тщательно управляйте сторонними скриптами аналитики — если возможно, используйте скрипты, которые учитывают предварительную отрисовку (например, используйте свойство
Document.prerenderingдля отсрочки выполнения на страницах предварительной отрисовки), такие как Google Analytics или NewRelic.- Обратите внимание, что загрузка содержимого кроссдоменных
<iframe>откладывается во время предварительной отрисовки до момента активации. Это делается для предотвращения ошибок, вызванных загрузкой кроссдоменных страниц, которые не знают о предварительной отрисовке, и для избежания сложностей с тем, какие учётные данные и кэш отобразить этим фреймам. Это означает, что в некоторых случаях пользователи первоначально могут видеть пустые фреймы, но также означает, что большинство сторонних виджетов, таких как рекламные технологии, безопасны для использования во время предварительной отрисовки. - Для сторонних скриптов, которые не учитывают предварительную отрисовку, избегайте их загрузки до активации с помощью события
prerenderingchange, как упоминалось ранее.
- Обратите внимание, что загрузка содержимого кроссдоменных
Состояние, изменяющееся на сервере
Существует два основных типа состояния, отображаемого на сервере, которые необходимо учитывать: устаревшее состояние и состояние, зависящее от пользователя. Это может привести к небезопасной предварительной загрузке и предварительному рендерингу.
- Устаревшее состояние: Рассмотрим пример списка комментариев к блогу, отображаемого на сервере, который может устареть между предварительным рендерингом записи блога и её просмотром. Это может быть особенно проблематично, если текущая страница — панель администратора, где пользователь удаляет спам-комментарии. Если затем пользователь переходит к записи блога, он может быть озадачен тем, почему всё ещё видит спам-комментарии, которые он только что удалил.
- Состояние, зависящее от пользователя: Рассмотрим пример отслеживания состояния входа через cookie. Проблемы могут возникнуть, например:
- Пользователь посещает
https://site.example/aв вкладке 1 иhttps://site.example/bво вкладке 2, будучи не авторизованным. -
https://site.example/bпредварительно рендеритhttps://site.example/c. Он будет предварительно рендерен в состоянии отсутствия авторизации. - Пользователь входит в систему на
https://site.exampleв вкладке 1. - Пользователь переключается на вкладку 2 и нажимает ссылку на
https://site.example/c, что активирует предварительно рендеренную страницу. - Вкладка 2 отображает представление неавторизованного пользователя
https://site.example/c, что вводит пользователя в заблуждение, так как он думал, что авторизован.
- Пользователь посещает
Проблемы со состоянием, зависящим от пользователя, могут возникать и для других пользовательских настроек, например, настроек языка, предпочтений тёмной темы или добавления элементов в корзину. Они также могут возникнуть, когда участвует только одна вкладка:
- Предположим, что пользователь посещает
https://site.example/product. -
https://site.example.com/productпредварительно рендеритhttps://site.example.com/cart. Он предварительно рендерит с 0 элементами в корзине. - Пользователь нажимает на кнопки "Добавить в корзину", что инициирует запрос fetch для добавления элемента в корзину пользователя (без перезагрузки страницы).
- Пользователь нажимает на ссылку на
https://site.example.com/cart, что активирует предварительно рендеренную страницу. - Пользователь видит пустую корзину, хотя только что что-то туда добавил.
Лучшим способом решения этих проблем, и, на самом деле, любого случая, когда содержимое может не синхронизироваться с сервером, является обновление страниц по мере необходимости. Например, сервер может использовать API канала обмена сообщениями, или другой механизм, такой как fetch() или WebSocket. Страницы затем могут соответствующим образом обновляться, включая страницы, загруженные с упреждением, которые ещё не активированы.
Поведение истории сеанса для предварительно рендеренных документов
Активация предварительно рендеренного документа ведет себя как любая обычная навигация с точки зрения конечного пользователя. Активированный документ отображается во вкладке и добавляется в историю сеанса, а все существующие записи в истории вперёд удаляются. Любые навигации, происходящие в контексте предварительного рендеринга до активации, не влияют на историю сеанса.
С точки зрения разработчика, предварительно рендеренный документ можно рассматривать как имеющий тривиальную историю сеанса, где существует только одна запись — текущая запись. Все навигации в контексте предварительного рендеринга эффективно заменяются.
Хотя API-функции, которые работают с историей сеанса (например, History и Navigation), могут вызываться в предварительно рендеренных документах, они работают только с тривиальной историей сеанса контекста. Следовательно, предварительно рендеренные документы не участвуют в общей истории сеанса страницы-источника. Например, они не могут перейти к странице-источнику с помощью History.back().
Эта конструкция гарантирует, что пользователи получат ожидаемый опыт при использовании кнопки "Назад" — т.е. что они вернутся к последнему увиденному элементу. После активации предварительно рендеренного документа в общую историю сеанса добавляется только одна запись, игнорируя все предыдущие навигации, которые произошли в контексте предварительного рендеринга. Возврат на один шаг назад в общей истории сеанса, например, нажатием кнопки "Назад", возвращает пользователя на страницу-источник.
Функции платформы, отложенные или ограниченные во время предварительного рендеринга
Поскольку предварительно рендеренная страница открывается в скрытом состоянии, ряд функций API, которые вызывают потенциально навязчивое поведение, не активируются в этом состоянии и вместо этого откладываются до активации страницы. Другие функции веб-платформы, которые проблематичны при предварительном рендеринге, полностью ограничены. В этом разделе подробно описываются функции, которые откладываются или ограничиваются.
Примечание: В небольшом количестве случаев, когда откладывание и ограничение невозможны, предварительный рендеринг отменяется.
Отложенные асинхронные API
Отложенные функции API сразу возвращают ожидающее promise и ничего не делают до активации страницы. После активации функция выполняется в обычном режиме, и promise разрешается или отклоняется как обычно.
Результаты следующих асинхронных функций откладываются в предварительно рендеренных документах до их активации:
-
API устройств вывода звука:
MediaDevices.selectAudioOutput() -
API фоновой загрузки:
BackgroundFetchManager.fetch() -
API канала обмена сообщениями:
BroadcastChannel.postMessage() -
API управления учётными данными:
CredentialsContainer.create(),CredentialsContainer.get(),CredentialsContainer.store() -
Расширения API шифрованного медиа:
Navigator.requestMediaKeySystemAccess() -
API игровых контроллеров:
Navigator.getGamepads(),gamepadconnectedсобытие,gamepaddisconnectedсобытие -
API геолокации:
Geolocation.getCurrentPosition(),Geolocation.watchPosition(),Geolocation.clearWatch() -
HTMLMediaElementAPI: позиция воспроизведения не будет изменяться, пока документ находится в процессе предварительного рендеринга -
API обнаружения простоя:
IdleDetector.start() -
API захвата медиа и потоков:
MediaDevices.getUserMedia()(и устаревшая версияNavigator.getUserMedia()),MediaDevices.enumerateDevices() -
API уведомлений:
Notification()конструктор,Notification.requestPermission() -
API push-уведомлений:
PushManager.subscribe() -
API ориентации экрана:
ScreenOrientation.lock(),ScreenOrientation.unlock() -
API датчиков:
Sensor.start() -
API сервисных рабочих процессов:
ServiceWorker.postMessage(),ServiceWorkerContainer.register(),ServiceWorkerRegistration.update(),ServiceWorkerRegistration.unregister() -
API хранения данных:
StorageManager.persist() -
Web Audio API:
AudioContextзапрещены во время предварительного рендеринга -
Web Bluetooth API:
Bluetooth.getDevices(),Bluetooth.requestDevice() -
WebHID API:
HID.getDevices(),HID.requestDevice() -
Web Locks API:
LockManager.query(),LockManager.request() -
Web MIDI API:
Navigator.requestMIDIAccess() -
Web NFC API:
NDefReader.write(),NDefReader.scan() -
Web Serial API:
Serial.getPorts(),Serial.requestPort() -
Web Speech API:
SpeechRecognition.abort(),SpeechRecognition.start(),SpeechRecognition.stop(),SpeechSynthesis.cancel(),SpeechSynthesis.pause(),SpeechSynthesis.resume(),SpeechSynthesis.speak() -
WebUSB API:
USB.getDevices(),USB.requestDevice() -
WebXR Device API:
XRSystem.requestSession()
Неявные ограниченные API
Следующие возможности будут автоматически отклоняться или не выполняться в документах, которые не активированы.
API, которые требуют временной активации или постоянной активации:
- Диалоговые окна подтверждения, генерируемые событием
beforeunload - Выполнение любых событий в API буфера обмена.
-
API файловой системы:
Window.showDirectoryPicker(),Window.showOpenFilePicker(),Window.showSaveFilePicker() -
API полноэкранного режима:
Element.requestFullscreen() -
API определения бездействия:
IdleDetector.requestPermission() -
API клавиатуры:
Keyboard.lock()(который требует полноэкранного режима) -
API запроса платежа:
PaymentRequest.show() -
API презентации:
PresentationRequest.start() -
API блокировки указателя:
Element.requestPointerLock() -
API захвата экрана:
MediaDevices.getDisplayMedia() -
API совместного использования веб-контента:
Navigator.share() Window.open()
API, которые требуют фокусировки содержащего документа:
API, которые требуют, чтобы состояние видимости содержащего документа Document.visibilityState было "visible":
-
API "картинка в картинке":
HTMLVideoElement.requestPictureInPicture()(требует состояния видимости содержащего документа `"visible", или временной активации) -
API блокировки пробуждения экрана:
WakeLock.request()
Другие ограниченные возможности
- Ссылки для скачивания, т.е.
<a>и<area>элементы с атрибутомdownload, будут отложены до завершения предварительной отрисовки. - Отсутствуют межсайтовые переходы: любой документ предварительной отрисовки, который переходит на другой сайт, будет немедленно отброшен перед отправкой запроса на этот другой сайт.
- Ограниченные URL-адреса: документы предварительной отрисовки не могут содержать URL-адреса верхнего уровня, отличные от HTTP(S). Включение следующих типов URL-адресов приведет к немедленному отказу от предварительной отрисовки:
javascript:URL-адресаdata:URL-адреса-
blob:URL-адреса -
about:URL-адреса, включаяabout:blankиabout:srcdoc
- Хранилище сеанса:
Window.sessionStorageможет быть использовано, но поведение очень специфично, чтобы не сломать сайты, которые ожидают, что только одна страница будет обращаться к хранилищу сеансов вкладки одновременно. Таким образом, предварительно отрисованная страница начинает с копии состояния хранилища сеанса вкладки, когда она была создана. При активации копия хранилища предварительно отрисованной страницы удаляется, и вместо этого используется основное состояние хранилища вкладки. Страницы, использующие хранилище сеанса, могут использовать событиеprerenderingchangeдля обнаружения момента, когда произойдет эта замена хранилища. -
Window.print(): Любые вызовы этого метода игнорируются. - "Простые методы диалога" ограничены следующим образом:
-
Window.alert()сразу же возвращает значение без отображения диалога. -
Window.confirm()сразу же возвращает значениеfalseбез отображения диалога. -
Window.prompt()сразу же возвращает пустую строку ("") без отображения диалога.
-
- Скрипты выделенных/совместных рабочих потоков загружаются, но их выполнение откладывается до активации предварительно отрисованного документа.
- Загрузки междоменных
<iframe>задерживаются во время предварительной отрисовки до активации страницы.
Интерфейсы
API правил спекуляций не определяет собственных интерфейсов.
Расширения других интерфейсов
-
Document.prerenderingЭкспериментально -
Логическое свойство, которое возвращает
true, если документ в настоящее время находится в процессе предварительной отрисовки. -
prerenderingchangeсобытие Экспериментально -
Срабатывает в предварительно отрисованном документе при его активации (т. е. когда пользователь просматривает страницу).
-
Число, представляющее время между началом предварительной отрисовки документа и его активацией.
-
PerformanceResourceTiming.deliveryType"navigational-prefetch"значение Экспериментально -
Указывает, что тип записи производительности — предзагрузка.
HTTP-заголовки
-
Content-Security-Policy'inline-speculation-rules'значение Экспериментально -
Используется для разрешения использования
<script type="speculationrules">для определения правил спекуляций в запрашиваемом документе. -
Speculation-RulesЭкспериментально -
Предоставляет список URL-адресов, указывающих на текстовые ресурсы, содержащие определения правил спекуляций в формате JSON. При ответе в формате HTML эти правила будут добавлены в набор правил спекуляций документа.
-
Supports-Loading-ModeЭкспериментально -
Устанавливается целевым объектом перехода для включения различных режимов загрузки с более высоким риском. Например, для предварительной отрисовки в другом домене, с таким же сайтом, необходимо значение
Supports-Loading-Modecredentialed-prerender.
Особенности HTML
-
<script type="speculationrules">Экспериментально -
Используется для определения набора правил спекуляций предзагрузки и/или предварительной отрисовки внутри текущего документа, которые добавляются в набор правил спекуляций документа.
Примеры
Полный демонстрационный пример предварительной отрисовки можно найти по адресу здесь.
Спецификации
Совместимость с браузерами
| Рабочий стол | Мобильное устройство | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari на IOS | Samsung Internet | WebView Android | |
Speculation_Rules_API |
109105Первоначальная поддержка включала только предрендеринг из одного источника. |
109105Первоначальная поддержка включала только предрендеринг из одного источника. |
Нет | 9591Первоначальная поддержка включала только предрендеринг из одного источника. |
Нет | 109103Первоначальная поддержка включала только предрендеринг из одного источника. |
Нет | 7471Первоначальная поддержка включала только предрендеринг из одного источника. |
Нет | 21.020.0Первоначальная поддержка включала только предрендеринг из одного источника. |
Нет |
eagerness |
121 | 121 | Нет | 107 | Нет | 121 | Нет | 81 | Нет | 25.0 | Нет |
expects_no_vary_search |
127121Поддерживается только дляprefetch. |
127121Поддерживается только дляprefetch. |
Нет | 113107Поддерживается только дляprefetch. |
Нет | 127121Поддерживается только дляprefetch. |
Нет | 8481Поддерживается только дляprefetch. |
Нет | 25.0Поддерживается только дляprefetch. |
Нет |
prefetch |
110 | 110 | Нет | 96 | Нет | 103 | Нет | 71 | Нет | 20.0 | Нет |
prerender |
105 | 105 | Нет | 91 | Нет | 103 | Нет | 71 | Нет | 20.0 | Нет |
referrer_policy |
111 | 111 | Нет | 97 | Нет | 111 | Нет | 75 | Нет | 22.0 | Нет |
| Рабочий стол | Мобильное устройство | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari на IOS | Samsung Internet | WebView Android | |
Speculation_Rules_API |
108 | 108 | Нет | 94 | Нет | 108 | Нет | 73 | Нет | 21.0 | 108 |
| Рабочий стол | Мобильное устройство | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari на IOS | Samsung Internet | WebView Android | |
Speculation_Rules_API |
108 | 108 | Нет | 94 | Нет | 108 | Нет | 73 | Нет | 21.0 | 108 |
api.Document.prerendering
Таблицы BCD загружаются только в браузере
api.Document.prerenderingchange_event
Таблицы BCD загружаются только в браузере
html.elements.script.type.speculationrules
Таблицы BCD загружаются только в браузере
См. также
- Предварительная загрузка страниц в Chrome для мгновенных переходов по страницам на developer.chrome.com (2023)
- Спекулятивная загрузка для сравнения правил спекуляции и других подобных функций повышения производительности.
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/Speculation_Rules_API