API возврата/пересылки notRestoredReasons

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

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

Текущий статус

API notRestoredReasons появился в Chrome 123 и внедряется постепенно.

Понятия и использование

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

Ранее разработчики не могли узнать, почему их страницы были заблокированы от использования bfcache в полевых условиях, хотя был тест в Chrome dev tools . Чтобы включить мониторинг в полевых условиях, класс PerformanceNavigationTiming был расширен, включив свойство notRestoredReasons . Это возвращает объект, содержащий связанную информацию о верхнем фрейме и всех iframe, присутствующих в документе:

  • Причины, по которым им было запрещено использовать bfcache.
  • Такие данные, как id и name фрейма, помогают идентифицировать фреймы в HTML.

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

Примеры

Экземпляр PerformanceNavigationTiming можно получить с помощью таких функций, как Performance.getEntriesByType() и PerformanceObserver .

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

function returnNRR() {
  const navEntries = performance.getEntriesByType("navigation");
  for (let i = 0; i < navEntries.length; i++) {
    console.log(`Navigation entry ${i}`);
    let navEntry = navEntries[i];
    console.log(navEntry.notRestoredReasons);
  }
}

Для навигации по истории свойство PerformanceNavigationTiming.notRestoredReasons возвращает объект со следующей структурой, которая представляет заблокированное состояние фрейма верхнего уровня:

{
  children: [],
  id: null,
  name: null,
  reasons: [
    {"reason", "unload-listener"}
  ],
  src: null,
  url: "https://www.example.com/page/"
}

Свойства следующие:

children
Массив объектов, представляющих заблокированное состояние любых кадров того же происхождения, встроенных в кадр верхнего уровня. Каждый объект имеет ту же структуру, что и родительский объект — таким образом, любое количество уровней встроенных кадров может быть представлено внутри объекта рекурсивно. Если у кадра нет дочерних элементов, массив будет пустым.
id
Строка, представляющая значение атрибута id фрейма (например <iframe id="foo" src="..."> ). Если фрейм не имеет id , значение будет null . Для страницы верхнего уровня это null .
name
Строка, представляющая значение атрибута name фрейма (например <iframe name="bar" src="..."> ). Если у фрейма нет name , значение будет пустой строкой. Для страницы верхнего уровня это null .
reasons
Массив строк, каждая из которых представляет причину, по которой навигируемая страница была заблокирована от использования bfcache. Существует множество различных причин, по которым может произойти блокировка. Подробнее см. в разделе Причины блокировки .
src
Строка, представляющая путь к источнику фрейма (например <iframe src="b.html"> ). Если фрейм не имеет src , значение будет пустой строкой. Для страницы верхнего уровня это null .
url
Строка, представляющая URL-адрес просмотренной страницы/iframe.

Для объектов PerformanceNavigationTiming , которые не представляют историю переходов, свойство notRestoredReasons будет возвращать null .

Обратите внимание, что notRestoredReasons также возвращает null , когда нет блокирующих причин, поэтому его значение null не является показателем того, использовался ли bfcache или нет. Для этого необходимо использовать свойство event.persisted .

Сообщить о блокировке bfcache во фреймах одного источника

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

Например:

{
  children: [
    {
      children: [],
      id: "iframe-id",
      name: "iframe-name",
      reasons: [],
      src: "./index.html",
      url: "https://www.example.com/"
    },
    {
      children: [],
      id: "iframe-id2",
      name: "iframe-name2",
      reasons: [
        {"reason": "unload-listener"}
      ],
      src: "./unload-examples.html",
      url: "https://www.example.com/unload-examples.html"
    },
  ],
  id: null,
  name: null,
  reasons: [],
  src: null,
  url:"https://www.example.com"
}

Сообщить о блокировке bfcache в кросс-источниковых фреймах

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

Например:

{
  children: [
    {
      children: [],
      id: "iframe-id",
      name: "iframe-name",
      reasons: [],
      src: "./index.html",
      url: "https://www.example2.com/"
    }
  ],
  id: null,
  name: null,
  reasons: [
        {"reason": "masked"}
  ],
  src: null,
  url:"https://www.example.com"
}

Для всех кросс-источниковых iframes мы сообщаем null для значения reasons для фрейма, а фрейм верхнего уровня будет показывать причину "masked" . Обратите внимание, что "masked" может также использоваться для причин, специфичных для пользовательского агента, поэтому не всегда может указывать на проблему в iframe.

Более подробную информацию о вопросах безопасности и конфиденциальности см. в разделе «Безопасность и конфиденциальность» в пояснительной записке.

Причины блокировки

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

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

  • unload-listener : страница регистрирует обработчик unload , который предотвращает использование bfcache в некоторых браузерах. Для получения дополнительной информации см. Устаревание события unload .
  • response-cache-control-no-store : Страница использует no-store в качестве значения cache-control .
  • related-active-contents : Страница была открыта с другой страницы (либо с помощью «дублирующей вкладки»), которая все еще имеет ссылку на эту страницу.

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

Команда Chromium хочет узнать о вашем опыте работы с API bfcache notRestoredReasons .

Расскажите нам о дизайне API

Есть ли что-то в API, что работает не так, как вы ожидали? Или отсутствуют методы или свойства, которые вам нужны для реализации вашей идеи? У вас есть вопрос или комментарий по модели безопасности? Отправьте запрос спецификации в соответствующий репозиторий GitHub или добавьте свои мысли в существующий запрос.

Сообщить о проблеме с реализацией

Вы нашли ошибку в реализации Chromium? Или реализация отличается от спецификации? Сообщите об ошибке в нашем трекере ошибок. Обязательно включите как можно больше подробностей, простые инструкции по воспроизведению и укажите компонент как UI > Browser > Navigation > BFCache .

Показать поддержку API

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

Отправьте твит @ChromiumDev , используя хэштег #NotRestoredReasons , и расскажите нам, где и как вы его используете.

Полезные ссылки