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

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

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

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

API notRestoredReasons был включен в Chrome версии 123 и постепенно внедряется.

Понятия и применение

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

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

  • Причины, по которым им было запрещено использовать bfcache.
  • Такие детали, как id и name фрейма, помогают идентифицировать iframe в 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"
}

Для всех iframe-элементов, содержащих данные из разных источников, значение reasons для фрейма будет null , а для фрейма верхнего уровня будет отображаться причина "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 , и расскажите нам, где и как вы его используете.

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