Publicado em 7 de março de 2025
A API Speculation Rules permite que os usuários se beneficiem de um aumento de desempenho ao pré-carregar ou pré-renderizar futuras navegações de página para oferecer navegações mais rápidas ou até mesmo instantâneas.
A API foi projetada especificamente para facilitar a implementação, mas há algumas considerações que sites complexos precisam considerar antes de usá-la. Este guia ajuda os proprietários de sites a entender essas considerações.
Planejamento
Antes de implementar as regras de especulação, é importante considerar como implementar a API (já que há algumas opções) e também os custos das especulações (que devem orientar você sobre quais páginas especular).
Decidir como implementar as regras de especulação
Uma das primeiras decisões que você precisa tomar é como implementar as regras de especulação no seu site, já que existem vários métodos que podem ser usados:
- Diretamente no HTML da página
- Usando o JavaScript
- Como usar um cabeçalho HTTP
No final das contas, todos os métodos têm o mesmo efeito, mas podem haver vantagens em termos de facilidade de implementação e flexibilidade.
Os sites devem escolher a opção mais adequada e podem até usar uma combinação dessas opções, se necessário. Como alternativa, elas podem ser implementadas usando um plug-in (como o plug-in de carregamento especulativo para WordPress) ou bibliotecas ou plataformas que podem fazer a escolha por você, mas ainda vale a pena conhecer as opções disponíveis.
Incluir regras de especulação diretamente no HTML da página
As regras de especulação podem ser implementadas diretamente na página incluindo o elemento <script type="speculationrules">
no HTML. Isso pode ser adicionado no momento do build para sites estáticos usando modelos ou no momento da execução pelo servidor quando a página é solicitada. Elas podem até ser injetadas no HTML por workers de borda, embora o método de cabeçalho HTTP discutido mais adiante neste guia seja provavelmente mais fácil para isso.
Isso permite incluir regras estáticas em todo o site, mas as regras de documento ainda podem ser dinâmicas, permitindo que você escolha os URLs a serem renderizados na página usando regras a serem acionadas por classes CSS:
<script type="speculationrules">
{
"prerender": [{
"where": { "selector_matches": ".prerender" }
}],
"prefetch": [{
"where": { "selector_matches": ".prefetch" }
}]
}
</script>
O script anterior vai pré-renderizar links com uma classe prerender
e, da mesma forma, fazer pré-carregamento quando um link tiver uma classe prefetch
. Isso permite que os desenvolvedores incluam essas classes no HTML para acionar as especulações.
Além de incluir links para essas classes no HTML inicial de uma página, os links também serão especulados se essas classes forem adicionadas dinamicamente pelo app, o que permite que o app acione (e remova) as especulações conforme necessário. Isso pode ser mais simples do que criar ou remover regras de especulação mais específicas. Também é possível incluir várias regras de especulação por página se você quiser uma regra de base usada pela maior parte do site e regras específicas da página.
Como alternativa, se você precisar usar regras de especulação mais específicas, as regras específicas da página ou do modelo podem permitir regras diferentes para determinadas páginas ou tipos de página.
Por fim, as páginas renderizadas no servidor também podem ter regras mais dinâmicas com base nas informações disponíveis para o servidor, como dados de análise da página ou jornadas de usuários comuns para determinadas páginas.
Adicionar regras de especulação usando JavaScript
Uma alternativa para incluir as regras em um script na página é injetá-las usando JavaScript. Isso pode exigir menos atualizações nos modelos de página. Por exemplo, ter um Gerenciador de tags que insere as regras pode ser uma maneira rápida de lançar as regras de especulação e também permite desativá-las rapidamente, se necessário.
Essa opção também permite regras dinâmicas do lado do cliente com base na interação do usuário com a página. Por exemplo, se o usuário adicionar um item ao carrinho, você poderá pré-renderizar a página de finalização da compra. Também é possível usar isso para acionar especulações com base em determinadas condições. Embora a API inclua uma configuração de prontidão que permite regras básicas de interação, o JavaScript permite que os desenvolvedores usem a própria lógica para decidir quando e em quais páginas fazer a estimativa.
Como mencionado anteriormente, uma abordagem alternativa para inserir novas regras é ter uma regra de documento de base na página e acionar regras de documento JavaScript adicionando classes adequadas aos links para que eles correspondam à regra.
Adicionar regras de especulação usando um cabeçalho HTTP
A última opção para os desenvolvedores é incluir as regras usando um cabeçalho HTTP:
Speculation-Rules: "/speculationrules.json"
Há alguns requisitos adicionais sobre como o recurso de regras (/speculationrules.json
neste exemplo) é entregue e usado.
Essa opção facilita a implantação por CDNs sem a necessidade de alterar o conteúdo do documento. Isso significa que alterar as regras de especulação dinamicamente usando JavaScript não é uma opção. No entanto, as regras de documentos com acionadores de seletor CSS ainda podem permitir mudanças dinâmicas, por exemplo, removendo a classe prerender
de um link.
Assim como na opção JavaScript, a implementação de regras de especulação com um cabeçalho HTTP permite que elas sejam implementadas independentemente do conteúdo do site, o que pode facilitar a adição e a remoção das regras sem a necessidade de recriar o site.
Considere as implicações de custo
Antes de implementar as regras de especulação, é importante considerar as implicações de custo para os usuários e seu site com essa API. Os custos incluem largura de banda (que custa dinheiro para usuários e sites) e custos de processamento (do lado do cliente e do servidor).
Considere o custo para os usuários
Carregar especulativamente significa fazer uma estimativa de onde um usuário pode navegar para uma nova página. No entanto, se essa navegação não acontecer, você pode ter desperdiçado recursos. Por isso, você precisa estar ciente do impacto nos usuários, principalmente:
- Largura de banda extra usada para fazer o download dessa navegação futura, especialmente em dispositivos móveis, onde a largura de banda pode ser mais restrita.
- Custos de processamento extras para renderizar essas páginas ao usar a pré-renderização.
Com previsões totalmente precisas, não há custos extras, porque os visitantes vão visitar essas páginas em seguida. A única diferença é que esses custos são antecipados. No entanto, prever o futuro com precisão total é impossível, e quanto mais agressiva for a estratégia de especulação, maior será o risco de desperdício.
O Chrome considerou esse problema com cuidado, e a API inclui vários recursos que significam que o custo é muito menor do que você pensa. Em particular, ao reutilizar o cache HTTP e não carregar iframes entre origens, o custo da pré-renderização de uma navegação no mesmo site é geralmente consideravelmente menor do que uma página completa sem recursos em cache, tornando os carregamentos especulativos menos custosos do que se pode supor.
No entanto, mesmo com essas proteções, os sites precisam considerar cuidadosamente quais páginas devem ser especuladas e o custo do usuário dessas especulações. Bons candidatos para o carregamento especulativo incluem aqueles que podem ser razoavelmente previstos com um alto grau de confiança (talvez com base em análises ou jornadas de usuários comuns) e quando o custo é baixo (por exemplo, páginas menos ricas).
Também é importante considerar o que o JavaScript precisa atrasar até a ativação. Assim como o carregamento lento de conteúdo até que ele seja necessário, isso pode tornar os pré-renderizadores mais baratos, mas melhorar a experiência do usuário. Com especulações mais baratas, você pode se sentir à vontade para especular com mais frequência ou entusiasmo.
Quando isso não for possível, recomendamos uma estratégia menos agressiva usando regras de eagerness moderadas ou conservadoras. Como alternativa, você pode usar a pré-renderização, que tem um custo consideravelmente menor do que a pré-renderização quando a confiança é baixa. Em seguida, faça upgrade para uma pré-renderização completa se a confiança aumentar, por exemplo, quando um link é destacado ou clicado.
Considere a carga extra do back-end
Além dos custos extras do usuário, os proprietários de sites precisam considerar os próprios custos de infraestrutura. Se cada página resultar em duas, três ou até mais carregamentos, os custos do back-end podem aumentar com o uso dessa API.
Garantir que suas páginas e recursos sejam armazenados em cache reduz significativamente a quantidade de carga de origem e, portanto, o risco geral. Quando combinados com um CDN, os servidores de origem terão uma carga extra mínima, mas considere os aumentos de custo do CDN.
Um servidor ou CDN também pode ser usado para controlar os resultados da especulação, conforme identificado pelo cabeçalho HTTP de finalidade secundária. Por exemplo, o produto Speed Brain da Cloudflare só permite especulações que já estão armazenadas em cache no servidor de borda de um CDN e não envia solicitações de volta à origem.
No entanto, como os carregamentos especulativos geralmente são usados para carregamentos de página de mesma origem, os usuários já terão recursos compartilhados no cache do navegador, desde que eles sejam armazenáveis em cache. Portanto, uma especulação geralmente não é tão custosa quanto um carregamento de página completo.
Encontrar o equilíbrio entre especular demais ou muito pouco
A chave para aproveitar ao máximo a API Speculation Rules é encontrar o equilíbrio entre especular demais, ou seja, quando os custos são pagos desnecessariamente e a especulação não é usada, e especular muito conservadoramente, ou seja, muito pouco ou muito tarde, quando há pouco benefício.
Quando os custos são baixos (por exemplo, páginas pequenas e geradas de forma estática em cache em nós de borda do CDN), você pode ser mais agressivo com as especulações.
No entanto, para páginas maiores e mais ricas que talvez não possam ser armazenadas em cache na borda do CDN, é preciso ter mais cuidado. Da mesma forma, páginas que consomem muitos recursos podem usar a largura de banda da rede ou a capacidade de processamento, o que pode afetar negativamente a página atual. O objetivo da API é melhorar o desempenho, então as regressões de desempenho definitivamente não são o que queremos. Esse é outro motivo para manter as prerenders em uma ou duas páginas no máximo. Além disso, o Chrome limita a duas ou dez prerenders por vez, dependendo da rapidez.
Etapas para implementar regras de especulação
Depois de decidir como implementar as regras de especulação, você precisa planejar o que especular e como fazer isso. Sites mais simples, como blogs pessoais estáticos, podem pular direto para o pré-renderização completa de determinadas páginas, mas sites mais complexos têm outras complexidades a serem consideradas.
Começar com o pré-carregamento
A pré-busca geralmente é relativamente segura para a maioria dos sites, e essa é a abordagem inicial adotada por muitos, incluindo lançamentos em grande escala, como o Cloudflare e o WordPress.
Os principais problemas que você precisa conhecer são que, se o pré-carregamento de um URL causar mudanças de estado e custos do lado do servidor, principalmente para páginas não cacháveis. Idealmente, as mudanças de estado, por exemplo, o pré-carregamento de uma página /logout
, não devem ser implementadas como links GET
, mas, infelizmente, isso não é incomum na Web.
Esses URLs podem ser excluídos especificamente das regras:
<script type="speculationrules">
{
"prefetch": [{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": {"href_matches": "/logout"}}
]
},
"eagerness": "moderate"
}]
}
</script>
A pré-busca pode ser limitada a navegações comuns de uma página para outra ou para todos os links de mesma origem ao passar o cursor ou clicar usando a eagerness
moderate
ou conservative
configuração. A configuração conservative
tem o menor risco, mas também a menor recompensa em potencial. Se você começar por aí, tente avançar para pelo menos moderate
, mas o ideal é ir além disso para eager
, que vai gerar mais benefícios de desempenho. Depois, faça upgrade para prerender
, se for possível.
Prerenders de baixo risco
As especulações de pré-busca são mais fáceis de implantar, mas o benefício de desempenho final para a API é com a pré-renderização. Isso pode ter algumas considerações extras quando a página não é visitada logo após a especulação (que abordaremos na próxima seção), mas com um pré-render moderate
ou conservative
, em que a navegação provavelmente vai acontecer logo depois, pode ser uma próxima etapa de risco relativamente baixo.
<script type="speculationrules">
{
"prerender": [{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": {"href_matches": "/logout"}}
]
},
"eagerness": "moderate"
}]
}
</script>
Pré-buscar páginas comuns para melhorar as pré-renderizações não ansiosas
Uma tática comum é pré-carregar um número menor de páginas visitadas com frequência no carregamento com uma configuração eager
(especificando-as em uma lista de URLs ou usando selector_matches
) e, em seguida, pré-renderizar com uma configuração moderate
. Como o pré-carregamento de HTML provavelmente será concluído quando o cursor passar sobre o link, isso aumenta a pré-renderização no cursor sem um pré-carregamento.
<script type="speculationrules">
{
"prefetch": [{
"urls": ["next.html", "next2.html"],
"eagerness": "eager"
}],
"prerender": [{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": {"href_matches": "/logout"}}
]
},
"eagerness": "moderate"
}]
}
</script>
Prerenders anteriores
Embora as regras de documento moderate
permitam o uso de risco relativamente baixo da API com uma facilidade de implementação associada, muitas vezes isso não é suficiente para uma pré-renderização completa. Para conseguir as navegações instantâneas que essa API permite, provavelmente você vai precisar ir além e pré-renderizar as páginas com mais rapidez.
Isso é feito com uma lista estática de URLs (como o exemplo de pré-carregamento anterior) ou com selector_matches
identificando um pequeno número de URLs (de preferência uma ou duas páginas), com regras de documentos cobrindo os outros URLs:
<script type="speculationrules">
{
"prerender": [
{
"where": {
"selector_matches": : ".prerender"
},
"eagerness": "eager",
},
{
"where": {
"and": [
{ "href_matches": "/*" },
{ "not": {"href_matches": "/logout"}}
]
},
"eagerness": "moderate"
}
]
}
</script>
Isso pode exigir a análise de tráfego para ter a melhor chance de prever com precisão a próxima navegação. Entender as jornadas típicas dos clientes no seu site também pode ajudar a identificar bons candidatos para o carregamento especulativo.
A mudança para uma pré-renderização mais rápida também pode introduzir mais considerações sobre análises, anúncios e JavaScript e a necessidade de manter uma página pré-renderizada atualizada ou até mesmo cancelar ou atualizar as especulações em mudanças de estado.
Analytics, anúncios e JavaScript
Ao usar o prerender, sites mais complexos também precisam considerar o impacto na análise. Normalmente, não é necessário registrar uma visualização de página (ou anúncio) quando a página é especulada, e somente quando a especulação é ativada.
Alguns provedores de análise de dados (como o Google Analytics) e provedores de anúncios (como a Tag do publisher do Google) já oferecem suporte às regras de especulação e não registram visualizações até que a página seja ativada. No entanto, outros provedores ou análises personalizadas que você implementou podem precisar de mais consideração.
É possível adicionar verificações ao JavaScript para impedir a execução de bits específicos de código até que as páginas sejam ativadas ou mostradas e até mesmo envolver elementos <script>
inteiros nessas verificações. Quando as páginas usam gerenciadores de tags para injetar esses scripts, é possível lidar com todos eles de uma só vez atrasando o script do gerenciador de tags.
Da mesma forma, os gerenciadores de consentimento são uma oportunidade de atrasar scripts de terceiros até a ativação. O Google tem trabalhado com várias plataformas de gerenciamento de consentimento para que elas sejam compatíveis com a pré-renderização. Vamos ajudar quem quiser fazer o mesmo. A PubTech é uma dessas empresas que oferece aos desenvolvedores a opção de executar ou bloquear o JavaScript durante a pré-renderização.
Para o código do aplicativo, você pode adicionar uma mudança para atrasar a execução do código até a ativação, especialmente quando a página não exige que o código JavaScript seja renderizado. Essa é uma opção mais rápida e segura, mas significa que todo o código será executado de uma só vez na ativação. Isso pode resultar em muito trabalho no momento da ativação, o que pode afetar o INP, especialmente porque a página pode parecer totalmente carregada e pronta para interação.
Além disso, se algum conteúdo depender do JavaScript (por exemplo, conteúdo renderizado do lado do cliente), atrasar isso vai reduzir o impacto positivo na LCP e na CLS que a pré-renderização pode trazer. Uma abordagem mais direcionada para permitir que mais JavaScript seja executado durante a fase de pré-renderização resultará em uma experiência melhor, mas pode ser menos trivial de implementar.
Para sites mais complexos, pode ser uma boa estratégia começar atrasando muitas tags de script. No entanto, para aproveitar ao máximo a API, permitir que o JavaScript seja executado durante a pré-renderização é o objetivo final.
Os sites com problemas de análise ou anúncios também podem começar com o pré-carregamento, em que isso é menos preocupante, enquanto eles consideram o que precisa ser feito para oferecer suporte à pré-renderização.
Atualizar especulações de pré-renderização
Ao pré-renderizar páginas antes das navegações, há o risco de que a página pré-renderizada fique desatualizada. Por exemplo, em um site de e-commerce, uma página pré-renderizada pode incluir uma cesta de finalização de compra, seja uma cesta cheia de itens ou apenas um contador mostrando o número de itens na cesta em outras páginas. Se mais itens forem adicionados a um carrinho e uma página renderizada for acessada, o usuário vai ficar confuso ao ver o estado anterior do checkout.
Esse não é um problema novo, e quando os usuários têm várias guias abertas no navegador, eles enfrentam o mesmo problema. No entanto, com páginas pré-renderizadas, isso é mais provável e inesperado, já que o usuário não iniciou a pré-renderização conscientemente.
A API Broadcast Channel é uma maneira de permitir que uma página no navegador transmita atualizações como essa para outras páginas. Isso também resolveria o problema de várias guias. As páginas pré-renderizadas podem receber mensagens de transmissão, mas não podem enviar as próprias até serem ativadas.
Como alternativa, as páginas pré-renderizadas podem receber atualizações usando o servidor (usando um fetch()
periódico ou uma conexão WebSocket
), mas com possíveis atrasos nas atualizações.
Cancelar ou atualizar previsões de renderização
Atualizar uma página pré-renderizada é a abordagem recomendada para continuar usando páginas pré-renderizadas e evitar confusão para os usuários. Quando isso não for possível, é possível cancelar as especulações.
Isso também pode ser usado para permanecer dentro dos limites do Chrome se os sites quiserem pré-renderizar outras páginas com maior probabilidade de serem visitadas.
Para cancelar as especulações, você precisa remover as regras de especulação da página ou remover classes ou outros critérios de correspondência, se estiver usando essa abordagem. Como alternativa, a página especulada pode chamar window.close()
se detectar que não está mais atual. No entanto, se a página puder detectar isso, a melhor opção será atualizar o estado dela para que ela volte a ficar atualizada.
Também é possível reinserir essas regras (ou critérios de correspondência) para que as páginas sejam pré-renderizadas novamente. No entanto, manter uma página atualizada geralmente é a melhor opção, porque é menos trabalhoso. Depois que as regras de especulação forem removidas, a reinserção precisa ser concluída em uma nova microtarefa ou mais tarde, para que o navegador perceba as remoções e cancele as especulações. Uma abordagem para excluir e remover todos os scripts de regras de especulação é mostrada no exemplo a seguir:
async function refreshSpeculations() {
const speculationScripts = document.querySelectorAll('script[type="speculationrules"]');
for (const speculationScript of speculationScripts) {
// Get the current rules as JSON text
const ruleSet = speculationScript.textContent;
// Remove the existing script to reset prerendering
speculationScript.remove();
// Await for a microtask before re-inserting.
await Promise.resolve();
// Reinsert rule in a new speculation rules script
const newScript = document.createElement('script');
newScript.type = 'speculationrules';
newScript.textContent = ruleSet;
console.log(newScript);
// Append the new script back to the document
document.body.appendChild(newScript);
}
}
A remoção de regras cancela os pretendentes (ou pré-carregamentos) atuais, mas a reinserção das regras só especula regras imediatas ou imediatas (incluindo regras de lista de URLs que usam o padrão imediato). No entanto, as especulações moderadas ou conservadoras serão removidas, mas não serão acionadas automaticamente até que o link seja usado novamente.
Essa opção de atualização não é restrita a regras inseridas em JavaScript. As regras estáticas incluídas no HTML também podem ser removidas ou alteradas da mesma forma, já que essa é uma mudança padrão do DOM. As regras de especulação HTTP não podem ser removidas, mas os critérios de correspondência (por exemplo, classes prerender
) podem ser removidos e adicionados novamente pelo JavaScript.
O Chrome também está analisando a possibilidade de adicionar suporte a Clear-Site-Header para permitir que as respostas do servidor cancelem as pré-renderizações, por exemplo, quando uma solicitação de atualização da cesta é feita.
Medir o impacto
Depois de implementar as regras de especulação, é necessário medir o sucesso e não apenas presumir que o processo é mais rápido. Como mencionado anteriormente, a especulação excessiva pode causar regressões de desempenho se o cliente ou servidor estiver sobrecarregado.
Ao implementar com várias etapas (pré-renderização, pré-renderização de baixo risco e pré-renderização antecipada), você precisa medir cada etapa.
Como medir o sucesso
As regras de especulação devem ter um impacto positivo nas principais métricas de performance, como LCP (e possivelmente também CLS e INP), mas isso pode não ser óbvio nas métricas gerais do site. Isso ocorre porque os sites podem ser compostos principalmente por outros tipos de navegação (por exemplo, páginas de destino) ou porque as navegações de mesma origem já são rápidas o suficiente para que, mesmo que sejam melhoradas drasticamente, elas não afetem as métricas do percentil 75, conforme informado no Relatório de experiência do usuário do Chrome (CrUX).
É possível usar os tipos de navegação de página no CrUX para verificar qual porcentagem das navegações é navigate_cache
ou prerender
e se isso está aumentando com o tempo. No entanto, para uma análise detalhada, talvez seja necessário usar o monitoramento de usuários reais para segmentar os dados em navegações especuladas e saber o quanto elas são mais rápidas do que outras.
Como medir o uso e o desperdício
Outra consideração importante é medir se você está especulando nas páginas corretas. Isso evita o desperdício e garante que você segmente as melhores páginas para aproveitar essa API.
Infelizmente, a página que inicia as especulações não consegue ver diretamente o status das tentativas de especulação. Além disso, não é possível presumir que as tentativas foram acionadas, já que o navegador pode reter especulações em determinadas circunstâncias. Portanto, elas precisam ser medidas na própria página. Isso também exige a verificação de duas APIs para saber se a página está especulando ou já especulou:
if (document.prerendering) {
console.log("Page is prerendering");
} else if (performance.getEntriesByType("navigation")[0]?.activationStart > 0) {
console.log("Page has already prerendered");
} else {
console.log("This page load was not using prerendering");
}
Essa página pode registrar a tentativa de especulação nos servidores de back-end.
Uma complicação com a análise é que os provedores (como o Google Analytics) são compatíveis com a pré-renderização e ignoram as chamadas de análise até que a página seja ativada, mesmo chamadas de eventos separadas. Portanto, os usuários do Google Analytics precisam usar outra opção de geração de registros do servidor.
Também é possível fazer isso no lado do cliente, em que cada página pré-renderizada registra a pré-renderização no armazenamento compartilhado, e a página de chamada lê isso. localStorage
funciona melhor porque pode ser lido ao sair de uma página. O sessionStorage
não pode ser usado porque tem um tratamento especial para páginas pré-renderizadas. No entanto, localStorage
não é seguro para transações, e outras páginas podem estar atualizando isso ao mesmo tempo se várias páginas forem pré-renderizadas. Esta demonstração usa um hash exclusivo e entradas individuais para evitar problemas.
Conclusão
As regras de especulação oferecem a possibilidade de um aumento dramático na performance da página. Este guia oferece conselhos sobre considerações ao implementar essa API para evitar possíveis problemas e aproveitar ao máximo a API.
Planejar a implementação com antecedência evita retrabalho. Para sites mais complexos, é necessário um lançamento em várias etapas, começando com o pré-carregamento e depois passando para a pré-renderização de baixo risco e, em seguida, para a pré-renderização antecipada. Por fim, é importante medir as melhorias e qualquer uso e desperdício para garantir que você está usando a API da melhor forma possível.