API de cache de avanço e retorno notRestoredReasons

Descubra quais navegações foram impedidas de usar o bfcache e por quê.

A propriedade notRestoredReasons, adicionada à classe PerformanceNavigationTiming, informa se os frames presentes no documento foram impedidos de usar o bfcache na navegação e o motivo. Os desenvolvedores podem usar essas informações para identificar páginas que precisam de atualizações para se tornarem compatíveis com o bfcache, melhorando o desempenho do site.

Status atual

A API notRestoredReasons foi lançada no Chrome 123 e está sendo disponibilizada gradualmente.

Conceitos e uso

Os navegadores mais recentes oferecem um recurso de otimização para navegação no histórico chamado cache de avanço e retorno (bfcache). Isso permite uma experiência de carregamento instantâneo quando os usuários voltam para uma página que já visitaram. As páginas podem ser impedidas de entrar no bfcache ou ser removidas dele por diferentes motivos, alguns exigidos por uma especificação e outros específicos das implementações do navegador.

Antes, não havia como os desenvolvedores descobrirem por que as páginas deles eram impedidas de usar o bfcache em campo, embora houvesse um teste nas Ferramentas para desenvolvedores do Chrome. Para ativar o monitoramento em campo, a classe PerformanceNavigationTiming foi estendida para incluir uma propriedade notRestoredReasons. Isso retorna um objeto com informações relacionadas sobre o frame superior e todos os iframes presentes no documento:

  • Motivos pelos quais eles foram impedidos de usar o bfcache.
  • Detalhes como frame id e name, para ajudar a identificar iframes no HTML.

    Isso permite que os desenvolvedores entrem em ação para tornar essas páginas compatíveis com o bfcache, melhorando o desempenho do site.

Exemplos

Uma instância de PerformanceNavigationTiming pode ser recebida de recursos como Performance.getEntriesByType() e PerformanceObserver.

Por exemplo, você pode invocar a função a seguir para retornar todos os objetos PerformanceNavigationTiming presentes na linha do tempo de performance e registrar o notRestoredReasons deles:

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

Para navegações no histórico, a propriedade PerformanceNavigationTiming.notRestoredReasons retorna um objeto com a seguinte estrutura, que representa o estado bloqueado do frame de nível superior:

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

As propriedades são as seguintes:

children
Uma matriz de objetos que representam o estado bloqueado de qualquer frame de mesma origem incorporado ao frame de nível superior. Cada objeto tem a mesma estrutura que o objeto pai. Dessa forma, qualquer número de níveis de frames incorporados pode ser representado dentro do objeto de forma recursiva. Se o frame não tiver filhos, a matriz vai ficar vazia.
id
Uma string que representa o valor do atributo id do frame (por exemplo, <iframe id="foo" src="...">). Se o frame não tiver id, o valor será null. Para a página de nível superior, é null.
name
Uma string que representa o valor do atributo name do frame (por exemplo, <iframe name="bar" src="...">). Se o frame não tiver name, o valor será uma string vazia. Para a página de nível superior, é null.
reasons
Uma matriz de strings, cada uma representando um motivo pelo qual a página acessada foi impedida de usar o bfcache. Há muitos motivos para o bloqueio ocorrer. Consulte a seção Motivos do bloqueio para mais detalhes.
src
Uma string que representa o caminho para a origem do frame (por exemplo, <iframe src="b.html">). Se o frame não tiver src, o valor será uma string vazia. Para a página de nível superior, é null.
url
Uma string que representa o URL da página/iframe acessado.

Para objetos PerformanceNavigationTiming que não representam navegações no histórico, a propriedade notRestoredReasons vai retornar null.

O notRestoredReasons também retorna null quando não há motivos de bloqueio. Portanto, o fato de ser null não indica se o bfcache foi ou não usado. Para isso, use a propriedade event.persisted.

Informar o bloqueio do bfcache em frames de mesma origem

Quando uma página tem frames de mesma origem incorporados, o valor notRestoredReasons retornado contém um objeto dentro da propriedade children que representa o estado bloqueado de cada frame incorporado.

Exemplo:

{
  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"
}

Reportar o bloqueio do bfcache em frames entre origens

Quando uma página tem frames entre origens incorporados, limitamos a quantidade de informações compartilhadas sobre eles para evitar o vazamento de informações entre origens. Incluímos apenas informações que a página externa já conhece e se a subárvore de origem cruzada bloqueou o bfcache ou não. Não incluímos motivos de bloqueio ou informações sobre níveis mais baixos da subárvore (mesmo que alguns subníveis sejam da mesma origem).

Exemplo:

{
  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"
}

Para todos os iframes entre origens, informamos null para o valor reasons do frame, e o frame de nível superior mostra um motivo de "masked". O "masked" também pode ser usado por motivos específicos do user agent, então nem sempre indica um problema em um iframe.

Consulte a seção Segurança e privacidade na explicação para mais detalhes sobre as considerações de segurança e privacidade.

Motivos do bloqueio

Como dissemos anteriormente, há muitos motivos para o bloqueio ocorrer:

Veja a seguir exemplos de alguns dos motivos mais comuns para o bfcache não ser usado:

  • unload-listener: a página registra um gerenciador unload, o que impede o uso do bfcache em determinados navegadores. O Chrome não emite mais esse motivo a partir do Chrome 155, exceto quando os sites reativam os eventos unload. Consulte Descontinuação do evento de descarregamento para mais informações.
  • response-cache-control-no-store: a página usa no-store como um valor de cache-control.
  • related-active-contents: a página foi aberta em outra página (usando "duplicar guia") que ainda tem uma referência a ela.

Feedback

A equipe do Chromium quer saber sobre suas experiências com a API bfcache notRestoredReasons.

Fale sobre o design da API

Há algo na API que não funciona como você esperava? Ou faltam métodos ou propriedades para implementar sua ideia? Tem alguma pergunta ou comentário sobre o modelo de segurança? Registre um problema de especificação no repositório do GitHub correspondente ou adicione suas ideias a um problema atual.

Informar um problema com a implementação

Você encontrou um bug na implementação do Chromium? Ou a implementação é diferente da especificação? Registre um bug no Issue Tracker. Inclua o máximo de detalhes possível, instruções para reprodução e especifique o componente como UI > Browser > Navigation > BFCache.

Mostrar suporte para a API

Você planeja usar a API bfcache notRestoredReasons? Seu apoio público ajuda a equipe do Chromium a priorizar recursos e mostra a outros fornecedores de navegadores como é importante oferecer suporte a eles.

Envie um tweet para @ChromiumDev usando a hashtag #NotRestoredReasons e informe onde e como você está usando o recurso.

Links úteis