Pré-renderizar páginas no Chrome para navegação instantânea

Compatibilidade com navegadores

  • Chrome: 109.
  • Edge: 109.
  • Firefox: não é compatível.
  • Safari: não é compatível.

A equipe do Chrome trouxe de volta a pré-renderização completa de páginas futuras que um usuário provavelmente vai acessar.

Uma breve história do prerender

No passado, o Chrome oferecia suporte à sugestão de recurso <link rel="prerender" href="/next-page">, mas não tinha suporte amplo além do Chrome e não era uma API muito expressiva.

Essa pré-renderização legada que usa a dica de link rel=prerender foi descontinuada em favor da pré-busca sem estado, que buscava os recursos necessários para a página futura, mas não fazia a pré-renderização completa nem executava o JavaScript. A pré-busca sem estado ajuda a melhorar o desempenho da página, mas não oferece um carregamento de página instantâneo, como uma pré-renderização completa.

A equipe do Chrome reintroduziu a pré-renderização completa no Chrome. Para evitar complicações com o uso atual e permitir a expansão futura da pré-renderização, esse novo mecanismo não vai usar a sintaxe <link rel="prerender"...>, que permanece em vigor para a pré-busca sem estado, com a intenção de descontinuar esse recurso no futuro.

Como uma página é pré-renderizada?

Uma página pode ser pré-renderizada de quatro maneiras, todas com o objetivo de tornar a navegação mais rápida:

  1. Quando você digita um URL na barra de endereço do Chrome (também conhecida como "omnibox"), o Chrome pode pré-renderizar a página automaticamente se tiver uma alta confiança de que você vai visitar essa página com base no seu histórico de navegação anterior.
  2. Quando você usa a barra de favoritos, o Chrome pode pré-renderizar a página automaticamente se você mantiver o ponteiro sobre um dos botões de favoritos.
  3. Quando você digita um termo de pesquisa na barra de endereço do Chrome, o navegador pode pré-renderizar automaticamente a página de resultados da pesquisa, quando instruído a fazer isso pelo mecanismo de pesquisa.
  4. Os sites podem usar a API Speculation Rules para informar programaticamente ao Chrome quais páginas pré-renderizar. Isso substitui o que o <link rel="prerender"...> costumava fazer e permite que os sites pré-renderizem proativamente uma página com base nas regras de especulação. Elas podem existir de forma estática nas páginas ou ser injetadas dinamicamente pelo JavaScript conforme o proprietário da página achar melhor.

Em cada um desses casos, o pré-renderização se comporta como se a página tivesse sido aberta em uma guia de plano de fundo invisível e, em seguida, é "ativada" substituindo a guia em primeiro plano por essa página pré-renderizada. Se uma página for ativada antes de ser totalmente pré-renderizada, o estado atual dela será "em primeiro plano" e continuará sendo carregado, o que significa que você ainda pode ter uma boa vantagem.

Como a página pré-renderizada é aberta em um estado oculto, várias APIs que causam comportamentos intrusivos (por exemplo, prompts) não são ativadas nesse estado e são adiadas até que a página seja ativada. Nos poucos casos em que isso ainda não é possível, a pré-renderização é cancelada. A equipe do Chrome está trabalhando para expor os motivos de cancelamento de pré-renderização como uma API e também para aprimorar os recursos do DevTools e facilitar a identificação desses casos extremos.

Impacto da pré-renderização

A pré-renderização permite um carregamento de página quase instantâneo, conforme mostrado no vídeo abaixo:

Exemplo de impacto da pré-renderização.

O site de exemplo já é rápido, mas, mesmo assim, é possível notar como a pré-renderização melhora a experiência do usuário. Isso também pode ter um impacto direto nas Principais métricas da Web de um site, com LCP quase zero, CLS reduzido (já que qualquer CLS de carregamento acontece antes da visualização inicial) e INP melhorado (já que o carregamento precisa ser concluído antes da interação do usuário).

Mesmo que uma página seja ativada antes de ser totalmente carregada, ter uma vantagem inicial no carregamento da página melhora a experiência de carregamento. Quando um link é ativado enquanto a pré-renderização ainda está acontecendo, a página de pré-renderização é movida para o frame principal e continua carregando.

No entanto, a pré-renderização usa mais memória e largura de banda de rede. Cuidado para não sobrecarregar os recursos do usuário. Só pré-carregue quando houver uma grande probabilidade de navegação para a página.

Consulte a seção Como medir a performance para mais informações sobre como medir o impacto real da performance nas suas análises.

Conferir as previsões da barra de endereço do Chrome

No primeiro caso de uso, você pode conferir as previsões de URLs do Chrome na página chrome://predictors:

A página &quot;Chrome Predictors&quot; filtrada para mostrar previsões baixas (cinza), médias (âmbar) e altas (verde) com base no texto inserido.
Página "Chrome Predictors".

As linhas verdes indicam confiança suficiente para acionar a pré-renderização. Neste exemplo, digitar "s" gera uma confiança razoável (âmbar), mas, quando você digita "sh", o Chrome tem confiança suficiente para que você quase sempre navegue para https://sheets.google.com.

Esta captura de tela foi tirada em uma instalação relativamente nova do Chrome e filtrando previsões de confiança zero, mas se você consultar seus próprios preditores, provavelmente verá muito mais entradas e, possivelmente, mais caracteres necessários para atingir um nível de confiança alto o suficiente.

Esses preditores também são responsáveis pelas opções sugeridas na barra de endereço:

O recurso &quot;Typeahead&quot; da barra de endereço do Chrome
O recurso "Typeahead" da barra de endereço.

O Chrome vai atualizar continuamente os preditores com base nas suas digitações e seleções.

  • Para um nível de confiança maior que 50% (mostrado em âmbar), o Chrome faz a pré-conexão proativa ao domínio, mas não pré-renderiza a página.
  • Para um nível de confiança maior que 80% (mostrado em verde), o Chrome vai pré-renderizar o URL.

A API Speculation Rules

Para a opção de pré-renderização da API Speculation Rules, os desenvolvedores da Web podem inserir instruções JSON nas páginas para informar ao navegador quais URLs devem ser pré-renderizados:

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

Ou pelas regras do documento (disponível no Chrome 121), que renderiza previamente os links encontrados no documento com base em seletores href (com base na API de padrão de URL) ou 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>

A equipe do Chrome preparou um codelab sobre as regras de especulação que vai ajudar você a adicionar essas regras a um site.

Ansiedade

Compatibilidade com navegadores

  • Chrome: 121.
  • Edge: 121.
  • Firefox: não é compatível.
  • Safari: não é compatível.

Uma configuração eagerness é usada para indicar quando as especulações devem ser disparadas, o que é particularmente útil para regras de documentos:

  • immediate:é usada para especular o mais rápido possível, isto é, assim que as regras de especulação forem observadas.
  • eager:comporta-se de maneira idêntica à configuração immediate, mas, no futuro, vamos procurar situar entre immediate e moderate.
  • moderate:realiza especulações se você mantiver o ponteiro sobre um link por 200 milissegundos (ou no evento pointerdown se for antes, e no dispositivo móvel onde não há evento hover).
  • conservative:especula no ponteiro ou no toque.

O eagerness padrão para regras list é immediate. As opções moderate e conservative podem ser usadas para limitar as regras list a URLs com os quais um usuário interage em uma lista específica. No entanto, em muitos casos, as regras document com uma condição where adequada podem ser mais adequadas.

O eagerness padrão para regras document é conservative. Como um documento pode consistir em muitos URLs, o uso de immediate ou eager para regras document deve ser feito com cautela. Consulte também a seção Limites do Chrome a seguir.

A configuração de eagerness a ser usada depende do seu site. Para um site estático e leve, especular com mais empenho pode ter um custo baixo e ser benéfico para os usuários. Sites com arquiteturas mais complexas e payloads de página mais pesados podem preferir reduzir o desperdício especulando com menos frequência até receber um indicador mais positivo de intenção dos usuários para limitar o desperdício.

A opção moderate é um meio-termo, e muitos sites podem se beneficiar da seguinte regra de especulação, que renderizaria um link ao manter o ponteiro sobre ele por 200 milissegundos ou no evento pointerdown como uma implementação básica, mas poderosa, de regras de especulação:

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

Pré-busca

As regras de especulação também podem ser usadas para pré-carregar páginas sem uma pré-renderização completa. Essa pode ser uma boa primeira etapa no caminho para a pré-renderização:

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

Limites do Chrome

O Chrome tem limites para evitar o uso excessivo da API Speculation Rules:

ansiedade Pré-busca Pré-renderização
immediate / eager 50 10
moderate / conservative 2 (FIFO) 2 (FIFO)
Limites de especulação no Chrome.

As configurações moderate e conservative, que dependem da interação do usuário, funcionam de forma FIFO (first in, first out): depois de atingir o limite, uma nova especulação faz com que a mais antiga seja cancelada e substituída pela mais recente para economizar memória. Uma especulação cancelada pode ser acionada novamente, por exemplo, passando o cursor sobre o link. Isso vai resultar na especulação do URL novamente, substituindo a especulação mais antiga. Nesse caso, a especulação anterior vai ter armazenado em cache todos os recursos armazenáveis no cache HTTP para esse URL. Portanto, a especulação por mais tempo terá um custo reduzido. É por isso que o limite é definido como o limite modesto de 2. As regras de lista estática não são acionadas por uma ação do usuário e, portanto, têm um limite maior, já que não é possível para o navegador saber quais são necessárias e quando.

Os limites de immediate e eager também são dinâmicos. Portanto, remover um elemento de script de URL list vai criar capacidade ao cancelar as especulações removidas.

O Chrome também impede que as especulações sejam usadas em determinadas condições, incluindo:

  • Save-Data.
  • Economia de energia quando ativada e com pouca bateria.
  • Limitações de memória.
  • Quando a configuração "Pré-carregar páginas" está desativada (o que também é desativado explicitamente por extensões do Chrome, como o uBlock Origin).
  • Páginas abertas em guias em segundo plano.

O Chrome também não renderiza iframes de origem cruzada em páginas pré-renderizadas até a ativação.

Todas essas condições têm como objetivo reduzir o impacto de especulações excessivas quando isso é prejudicial aos usuários.

Como incluir regras de especulação em uma página

As regras de especulação podem ser incluídas de forma estática no HTML da página ou inseridas dinamicamente na página pelo JavaScript:

  • Regras de especulação incluídas de forma estática: por exemplo, um site de notícias ou um blog pode pré-render o artigo mais recente, se ele for a próxima navegação para uma grande proporção de usuários. Como alternativa, as regras de documentos com moderate ou conservative podem ser usadas para especular como os usuários interagem com links.
  • Regras de especulação inseridas de maneira dinâmica: podem ser baseadas na lógica do aplicativo, personalizadas para o usuário ou baseadas em outras heurísticas.

Aqueles que favorecem a inserção dinâmica com base em ações como passar o cursor ou clicar em um link, como muitas bibliotecas fizeram no passado com <link rel=prefetch>, devem consultar as regras de documentos, já que elas permitem que o navegador processe muitos dos seus casos de uso.

As regras de especulação podem ser adicionadas no <head> ou no <body> do frame principal. As regras de especulação em subframes não são aplicadas, e as regras de especulação em páginas pré-renderizadas só são aplicadas quando a página é ativada.

Cabeçalho HTTP Speculation-Rules

Compatibilidade com navegadores

  • Chrome: 121.
  • Edge: 121.
  • Firefox: não é compatível.
  • Safari: não é compatível.

Origem

As regras de especulação também podem ser enviadas usando um cabeçalho HTTP Speculation-Rules, em vez de incluí-las diretamente no HTML do documento. Isso facilita a implantação por CDNs sem a necessidade de alterar o conteúdo dos documentos.

O cabeçalho HTTP Speculation-Rules é retornado com o documento e aponta para um local de um arquivo JSON que contém as regras de especulação:

Speculation-Rules: "/speculationrules.json"

Esse recurso precisa usar o tipo MIME correto e, se for um recurso de origem cruzada, precisa passar por uma verificação do CORS.

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

Se você quiser usar URLs relativos, inclua a chave "relative_to": "document" nas regras de especulação. Caso contrário, os URLs relativos serão relativos ao URL do arquivo JSON das regras de especulação. Isso pode ser útil se você precisar selecionar alguns ou todos os links de mesma origem.

Regras de especulação e SPAs

As regras de especulação são compatíveis apenas com navegações de página completa gerenciadas pelo navegador, e não com apps de página única (SPA) ou páginas de shell do app. Essa arquitetura não usa buscas de documentos, mas sim buscas parciais de dados ou páginas da API, que são processadas e apresentadas na página atual. Os dados necessários para essas chamadas "navegação suave" podem ser pré-carregados pelo app fora das regras de especulação, mas não podem ser pré-renderizados.

As regras de especulação podem ser usadas para pré-renderizar o aplicativo em uma página anterior. Isso pode ajudar a compensar alguns dos custos de carregamento inicial extras que alguns SPAs têm. No entanto, as mudanças de rota no app não podem ser pré-renderizadas.

Depurar regras de especulação

Consulte a postagem dedicada sobre regras de especulação de depuração para conferir os novos recursos do Chrome DevTools que ajudam a visualizar e depurar essa nova API.

Várias regras de especulação

Várias regras de especulação também podem ser adicionadas à mesma página e anexadas às regras existentes. Portanto, as seguintes maneiras diferentes resultam na pré-renderização de one.html e two.html:

Lista de URLs:

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

Vários scripts speculationrules:

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

Várias listas em um conjunto de speculationrules

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

Compatibilidade com navegadores

  • Chrome: 121.
  • Edge: 121.
  • Firefox: não é compatível.
  • Safari: não é compatível.

Origem

Ao pré-carregar ou pré-renderizar uma página, alguns parâmetros de URL (tecnicamente conhecidos como parâmetros de pesquisa) podem não ser importantes para a página realmente entregue pelo servidor e usados apenas pelo JavaScript do lado do cliente.

Por exemplo, os parâmetros UTM são usados pelo Google Analytics para medir campanhas, mas geralmente não resultam em páginas diferentes sendo enviadas pelo servidor. Isso significa que page1.html?utm_content=123 e page1.html?utm_content=456 vão exibir a mesma página do servidor, para que ela possa ser reutilizada do cache.

Da mesma forma, os aplicativos podem usar outros parâmetros de URL que são processados apenas no lado do cliente.

A proposta No-Vary-Search permite que um servidor especifique parâmetros que não resultam em uma diferença no recurso entregue e, portanto, permite que um navegador reutilize versões armazenadas em cache de um documento que diferem apenas por esses parâmetros. Isso é compatível com o Chrome (e navegadores baseados no Chromium) para especulações de navegação de pré-carregamento, embora estejamos procurando oferecer suporte a isso também para pré-renderização.

As regras de especulação oferecem suporte ao uso de expects_no_vary_search para indicar onde um cabeçalho HTTP No-Vary-Search deve ser retornado. Isso pode ajudar a evitar downloads desnecessários.

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

Neste exemplo, o HTML da página inicial /products é o mesmo para os IDs de produto 123 e 124. No entanto, o conteúdo da página pode ser diferente com base na renderização do lado do cliente usando JavaScript para buscar dados de produtos com o parâmetro de pesquisa id. Portanto, fazemos o pré-carregamento desse URL e ele precisa retornar um cabeçalho HTTP No-Vary-Search mostrando que a página pode ser usada para qualquer parâmetro de pesquisa id.

No entanto, se o usuário clicar em qualquer um dos links antes da conclusão do pré-carregamento, o navegador poderá não ter recebido a página /products. Nesse caso, o navegador não sabe se ele vai conter o cabeçalho HTTP No-Vary-Search. O navegador pode escolher entre buscar o link novamente ou esperar a conclusão do pré-carregamento para verificar se ele contém um cabeçalho HTTP No-Vary-Search. A configuração expects_no_vary_search permite que o navegador saiba que a resposta da página deve conter um cabeçalho HTTP No-Vary-Search e aguardar a conclusão desse pré-carregamento.

Restrições das regras de especulação e melhorias futuras

As regras de especulação são restritas a páginas abertas na mesma guia, mas estamos trabalhando para reduzir essa restrição.

Por padrão, as especulações são restritas a páginas de mesma origem. Páginas de origem cruzada no mesmo site (por exemplo, https://a.example.com pode pré-renderizar uma página em https://b.example.com). Para usar isso, a página especulada (https://b.example.com neste exemplo) precisa ativar a inclusão de um cabeçalho HTTP Supports-Loading-Mode: credentialed-prerender, ou o Chrome vai cancelar a especulação.

Futuras versões também podem permitir a pré-renderização de páginas entre origens que não são do mesmo site, desde que não haja cookies na página pré-renderizada e ela aceite um cabeçalho HTTP Supports-Loading-Mode: uncredentialed-prerender semelhante.

As regras de especulação já oferecem suporte a pré-carregamentos entre origens, mas apenas quando os cookies do domínio entre origens não existem. Se houver cookies do usuário que já visitaram esse site, a especulação não será acionada e mostrará uma falha no DevTools.

Considerando essas limitações atuais, um padrão que pode melhorar a experiência dos usuários para links internos e externos, quando possível, é pré-renderizar URLs de mesma origem e tentar pré-renderizar URLs de origem cruzada:

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

A restrição para evitar especulações entre origens para links entre origens é necessária por padrão para fins de segurança. É uma melhoria em relação a <link rel="prefetch"> para destinos de origem cruzada, que também não envia cookies, mas ainda tenta o pré-carregamento, o que resulta em um pré-carregamento desperdiçado que precisa ser reenviado ou, pior ainda, no carregamento incorreto da página.

As regras de especulação não são compatíveis com o pré-carregamento de páginas controladas por service workers. Estamos trabalhando para adicionar esse suporte. Acompanhe as atualizações sobre este problema do service worker de suporte. A pré-renderização tem suporte para páginas controladas por service worker.

Detectar suporte à API Speculation Rules

É possível detectar o suporte à API Speculation Rules com verificações HTML padrão:

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

Adicionar regras de especulação dinamicamente pelo JavaScript

Este é um exemplo de como adicionar uma regra de especulação prerender com 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);
}

Confira uma demonstração da pré-renderização da API Speculation Rules usando a inserção de JavaScript nesta página de demonstração.

Inserir um elemento <script type = "speculationrules"> diretamente no DOM usando innerHTML não registra as regras de especulação por motivos de segurança, e isso precisa ser adicionado conforme mostrado anteriormente. No entanto, o conteúdo inserido dinamicamente usando innerHTML, que contém novos links, será selecionado pelas regras atuais na página.

Da mesma forma, a edição direta do painel Elements nas Ferramentas do desenvolvedor do Chrome para adicionar o elemento <script type = "speculationrules"> não registra as regras de especulação. Em vez disso, o script para adicionar isso dinamicamente ao DOM precisa ser executado no console para inserir as regras.

Adicionar regras de especulação usando um Gerenciador de tags

Para adicionar regras de especulação usando um gerenciador de tags, como o Gerenciador de tags do Google (GTM), é necessário inserir essas regras em JavaScript, em vez de adicionar o elemento <script type = "speculationrules"> diretamente no GTM, pelos mesmos motivos mencionados anteriormente:

Configuração de tag HTML personalizada no Gerenciador de tags do Google
Adicionar regras de especulação pelo Gerenciador de tags do Google.

Este exemplo usa var, porque o GTM não oferece suporte a const.

Cancelar regras de especulação

A remoção das regras de especulação vai resultar no cancelamento do pré-render, mas, quando isso acontecer, os recursos provavelmente já terão sido gastos para iniciar o pré-render. Portanto, é recomendável não usar o pré-render se houver a probabilidade de precisar cancelar.

Regras de especulação e Política de Segurança de Conteúdo

Como as regras de especulação usam um elemento <script>, mesmo que contenham apenas JSON, elas precisam ser incluídas na Content-Security-Policy script-src se o site usar isso, seja com um hash ou um valor de uso único.

Um novo inline-speculation-rules pode ser adicionado a script-src, permitindo que elementos <script type="speculationrules"> injetados de scripts hash ou nonced sejam aceitos. Isso não oferece suporte a regras incluídas no HTML inicial. Portanto, as regras precisam ser injetadas pelo JavaScript para sites que usam um CSP rígido.

Detectar e desativar a pré-renderização

A pré-renderização geralmente é uma experiência positiva para os usuários, porque permite a renderização rápida da página, muitas vezes instantânea. Isso beneficia tanto o usuário quanto o proprietário do site, já que as páginas pré-renderizadas permitem uma experiência do usuário melhor, o que pode ser difícil de alcançar de outra forma.

No entanto, pode haver casos em que você não quer que a pré-renderização de páginas aconteça, por exemplo, quando as páginas mudam de estado com base na solicitação inicial ou na execução do JavaScript na página.

Ativar e desativar o pré-render no Chrome

A pré-renderização só é ativada para usuários do Chrome com a configuração "Pré-carregar páginas" em chrome://settings/performance/. Além disso, o pré-render também é desativado em dispositivos com pouca memória ou se o sistema operacional estiver nos modos "Salvar dados" ou "Economia de energia". Consulte a seção Limites do Chrome.

Detectar e desativar a pré-renderização do lado do servidor

As páginas pré-renderizadas serão enviadas com o cabeçalho HTTP Sec-Purpose:

Sec-Purpose: prefetch;prerender

As páginas pré-buscadas que usam a API Speculation Rules terão esse cabeçalho definido como prefetch:

Sec-Purpose: prefetch

Os servidores podem responder com base nesse cabeçalho para registrar solicitações de especulação, retornar conteúdo diferente ou impedir que uma pré-renderização aconteça. Se um código de resposta final com falha for retornado, ou seja, não estiver no intervalo de 200 a 299 após os redirecionamentos, a página não será renderizada previamente, e qualquer página de pré-carregamento será descartada. Além disso, as respostas 204 e 205 não são válidas para pré-renderização, mas são válidas para pré-busca.

Se você não quiser que uma página específica seja pré-renderizada, retornar um código de resposta diferente de 2XX (como 503) é a melhor maneira de garantir que isso não aconteça. No entanto, para oferecer a melhor experiência, é recomendável permitir a pré-renderização, mas atrasar as ações que só devem acontecer quando a página for realmente visualizada, usando JavaScript.

Detectar pré-renderização em JavaScript

A API document.prerendering vai retornar true enquanto a página estiver em pré-renderização. Isso pode ser usado pelas páginas para impedir ou atrasar determinadas atividades durante o pré-render até que a página seja ativada.

Quando um documento pré-renderizado é ativado, o activationStart do PerformanceNavigationTiming também é definido como um tempo diferente de zero, representando o tempo entre o início da pré-renderização e a ativação do documento.

Você pode ter uma função para verificar páginas de pré-renderização e pré-renderização, como esta:

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

A maneira mais fácil de saber se uma página foi pré-renderizada (total ou parcialmente) é abrir o DevTools depois que a página for ativada e digitar performance.getEntriesByType('navigation')[0].activationStart no console. Se um valor diferente de zero for retornado, você saberá que a página foi pré-renderizada:

Console no Chrome DevTools mostrando um activationStart positivo indicando que a página foi pré-renderizada
Testando a pré-renderização no console.

Quando a página é ativada pelo usuário que a visualiza, o evento prerenderingchange é enviado no document, que pode ser usado para ativar atividades que antes eram iniciadas por padrão no carregamento da página, mas que você quer atrasar até que a página seja realmente visualizada pelo usuário.

Com essas APIs, o JavaScript de front-end pode detectar e agir de forma adequada nas páginas pré-renderizadas.

Impacto nas análises

As análises são usadas para medir o uso do site, por exemplo, usando o Google Analytics para medir visualizações de página e eventos. Ou medindo as métricas de desempenho das páginas usando o Monitoramento de usuários reais (RUM).

As páginas só devem ser pré-renderizadas quando houver uma alta probabilidade de serem carregadas pelo usuário. É por isso que as opções de pré-renderização da barra de endereço do Chrome só acontecem quando há uma probabilidade tão alta (mais de 80% do tempo).

No entanto, principalmente ao usar a API Speculation Rules, as páginas pré-renderizadas podem ter um impacto na análise, e os proprietários de sites podem precisar adicionar um código extra para ativar apenas a análise de páginas pré-renderizadas na ativação, já que nem todos os provedores de análise fazem isso por padrão.

Isso pode ser feito usando um Promise que aguarda o evento prerenderingchange se um documento estiver em pré-renderização ou resolve imediatamente se ele estiver agora:

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

Uma abordagem alternativa é atrasar as atividades de análise até que a página seja mostrada pela primeira vez, o que abrangeria tanto o caso de pré-renderização quanto quando as guias são abertas em segundo plano (por exemplo, com clique com o botão direito do mouse e abertura em uma nova guia):

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

Embora isso possa fazer sentido para análises e casos de uso semelhantes, em outros casos, talvez seja necessário carregar mais conteúdo. Nesses casos, use document.prerendering e prerenderingchange para segmentar especificamente as páginas de pré-renderização.

Reter outros conteúdos durante a pré-renderização

As mesmas APIs discutidas anteriormente podem ser usadas para reter outros conteúdos durante a fase de pré-renderização. Podem ser partes específicas do JavaScript ou elementos de script inteiros que você prefere não executar durante o estágio de pré-renderização.

Por exemplo, considerando este script:

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

É possível mudar isso para um elemento de script inserido dinamicamente que só insere com base na função whenActivated anterior:

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

Isso pode ser útil para reter scripts diferentes que incluem análises ou renderizar conteúdo com base no estado ou em outras variáveis que podem mudar durante a visita. Por exemplo, as recomendações, o estado de login ou os ícones do carrinho de compras podem ser retidos para garantir que as informações mais atualizadas sejam apresentadas.

Embora isso seja mais provável com o uso da pré-renderização, essas condições também são válidas para páginas carregadas em guias em segundo plano mencionadas anteriormente. Portanto, a função whenFirstVisible pode ser usada no lugar de whenActivated.

Em muitos casos, o estado também precisa ser verificado em mudanças gerais de visibilitychange. Por exemplo, ao retornar a uma página que estava em segundo plano, todos os contadores de carrinho de compras precisam ser atualizados com o número mais recente de itens no carrinho. Portanto, esse não é um problema específico do prerender, mas o prerender está apenas tornando um problema existente mais óbvio.

Uma maneira de o Chrome reduzir a necessidade de agrupar scripts ou funções manualmente é que certas APIs são retidas, conforme mencionado anteriormente, e também iframes de terceiros não são renderizados. Portanto, apenas o conteúdo acima é necessário para ser retido manualmente.

Avaliar o desempenho

Para medir as métricas de performance, a análise precisa considerar se é melhor medir com base no tempo de ativação ou no tempo de carregamento da página que as APIs do navegador vão informar.

As Core Web Vitals, medidas pelo Chrome no Relatório de experiência do usuário do Chrome, têm como objetivo medir a experiência do usuário. Elas são medidas com base no tempo de ativação. Isso geralmente resulta em uma LCP de 0 segundo, por exemplo, mostrando que essa é uma ótima maneira de melhorar as Core Web Vitals.

A partir da versão 3.1.0, a biblioteca web-vitals foi atualizada para processar navegações pré-renderizadas da mesma forma que o Chrome mede os Core Web Vitals. Essa versão também sinaliza navegações pré-renderizadas para essas métricas no atributo Metric.navigationType se a página foi pré-renderizada totalmente ou parcialmente.

Medir prerenders

É possível saber se uma página foi pré-renderizada com uma entrada activationStart diferente de zero de PerformanceNavigationTiming. Isso pode ser registrado usando uma dimensão personalizada ou algo semelhante ao registrar as visualizações de página, por exemplo, usando a função pagePrerendered descrita anteriormente:

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

Isso permite que a análise mostre quantas navegações são pré-renderizadas em comparação com outros tipos de navegação e também permite que você correlacione métricas de performance ou de negócios a esses diferentes tipos de navegação. Páginas mais rápidas significam usuários mais felizes, o que pode ter um impacto real nas métricas de negócios, como mostram nossos estudos de caso.

Ao medir o impacto comercial da pré-renderização de páginas para navegações instantâneas, você pode decidir se vale a pena investir mais esforço no uso dessa tecnologia para permitir que mais navegações sejam pré-renderizadas ou investigar por que as páginas não estão sendo pré-renderizadas.

Medir as taxas de ocorrência

Além de medir o impacto das páginas que são visitadas após uma pré-renderização, também é importante medir as páginas que são pré-renderizadas e não visitadas posteriormente. Isso pode significar que você está fazendo muitas pré-renderizações e usando recursos valiosos do usuário com pouco benefício.

Isso pode ser medido disparando um evento de análise quando as regras de especulação são inseridas, depois de verificar se o navegador oferece suporte à pré-renderização usando HTMLScriptElement.supports('speculationrules'), para indicar que a pré-renderização foi solicitada. O fato de uma pré-renderização ter sido solicitada não indica que ela foi iniciada ou concluída. Como observado anteriormente, uma pré-renderização é uma dica para o navegador, que pode optar por não pré-renderizar páginas nas configurações do usuário, no uso atual da memória ou em outras heurísticas.

Em seguida, compare o número desses eventos com as visualizações de página de pré-renderização. Ou, se preferir, acione outro evento na ativação para facilitar a comparação.

A "taxa de sucesso" pode ser aproximada analisando a diferença entre esses dois números. Para páginas em que você usa a API Speculation Rules para pré-renderizar as páginas, é possível ajustar as regras adequadamente para garantir uma taxa de acessos alta e manter o equilíbrio entre o uso dos recursos dos usuários para ajudar e o uso desnecessário.

Algumas pré-renderizações podem estar acontecendo devido à pré-renderização da barra de endereço, e não apenas às suas regras de especulação. Você pode verificar o document.referrer (que fica em branco para a navegação na barra de endereço, incluindo a navegação na barra de endereço pré-renderizada) se quiser diferenciar esses elementos.

Verifique também as páginas que não têm pré-renderizações, porque isso pode indicar que elas não estão qualificadas para pré-renderizações, mesmo na barra de endereço. Isso pode significar que você não está se beneficiando desse aprimoramento de desempenho. A equipe do Chrome quer adicionar ferramentas extras para testar a qualificação de pré-renderização, talvez semelhante à ferramenta de teste do bfcache, e também adicionar uma API para mostrar por que uma pré-renderização falhou.

Impacto nas extensões

Consulte a postagem dedicada sobre Extensões do Chrome: como estender a API para oferecer suporte à navegação instantânea, que detalha algumas considerações adicionais que os autores de extensões precisam considerar para páginas pré-renderizadas.

Feedback

A pré-renderização está em desenvolvimento ativo pela equipe do Chrome, e há muitos planos para ampliar o escopo do que foi disponibilizado na versão 108 do Chrome. Aceitamos qualquer feedback sobre o repositório do GitHub ou usando o rastreador de problemas. Além disso, queremos ouvir e compartilhar estudos de caso sobre essa nova API.

Agradecimentos

Imagem em miniatura de Marc-Olivier Jodoin no Unsplash