Os usuários que carregarem o site pela segunda vez usarão o cache HTTP. Portanto, verifique se ele funciona bem.
Esta postagem é complementar ao vídeo Ame seu cache, parte do conteúdo estendido do Chrome Dev Summit 2020. Confira o vídeo:
Quando os usuários carregam seu site pela segunda vez, o navegador usa recursos dentro do cache HTTP para ajudar a acelerar o carregamento. No entanto, os padrões de armazenamento em cache na Web datam de 1999 e são definidos de forma bastante ampla. Determinar se um arquivo, como CSS ou uma imagem, pode ser buscado novamente da rede em vez de ser carregado do cache é uma ciência um pouco imprecisa.
Nesta postagem, vou falar sobre um padrão moderno e sensato para armazenamento em cache, que na verdade não faz armazenamento em cache. Mas esse é apenas o padrão, e ele é, claro, mais complexo do que simplesmente "desativar". Siga em frente com a leitura.
Metas
Quando um site é carregado pela segunda vez, você tem dois objetivos:
- Garanta que os usuários tenham a versão mais atualizada disponível. Se você tiver feito alguma mudança, ela precisa ser refletida rapidamente.
- Faça a #1 enquanto extrai o mínimo possível da rede
No sentido mais amplo, você só quer enviar a menor mudança para seus clientes quando eles carregarem o site novamente. E estruturar seu site para garantir a distribuição mais eficiente de qualquer mudança é um desafio. Confira mais informações abaixo e no vídeo.
Dito isso, você também tem outras opções ao considerar o armazenamento em cache. Talvez você tenha decidido deixar o cache HTTP do navegador de um usuário reter seu site por um longo tempo para que nenhuma solicitação de rede seja necessária para exibi-lo. Ou você criou um service worker que vai veicular um site totalmente off-line antes de verificar se ele está atualizado. Essa é uma opção extrema, válida e usada em muitas experiências da Web com foco em apps off-line, mas a Web não precisa estar em um extremo de cache ou até mesmo de rede.
Contexto
Como desenvolvedores da Web, estamos acostumados com a ideia de ter um "cache desatualizado". Mas sabemos, quase por instinto, quais são as ferramentas disponíveis para resolver isso: faça uma "atualização forçada", abra uma janela anônima ou use uma combinação das ferramentas para desenvolvedores do seu navegador para limpar os dados de um site.
Os usuários comuns da Internet não têm esse luxo. Portanto, embora temos algumas metas principais de garantir que os usuários se divirtam muito com a segunda carga, também é muito importante garantir que eles não passem por momentos ou tenham dificuldades. Confira o vídeo para saber como quase bloqueamos o site web.dev/live.
Para entender melhor, um motivo muito comum para "cache desatualizado" é
o padrão da era de 1999 para armazenamento em cache. Ele depende do cabeçalho Last-Modified
:
Cada arquivo carregado é mantido por mais 10% da vida útil atual, conforme
o navegador o percebe. Por exemplo, se index.html
foi criado há um mês,
ele será armazenado em cache pelo navegador por mais três dias.
Essa era uma ideia bem intencionada, mas, devido à natureza integrada dos sites atuais, esse comportamento padrão significa que é possível chegar a um estado em que um usuário tem arquivos projetados para diferentes versões do seu site (por exemplo, o JS da versão de terça-feira e o CSS da versão de sexta-feira), tudo porque esses arquivos não foram atualizados exatamente ao mesmo tempo.
Caminho bem iluminado
Um padrão moderno para o armazenamento em cache é não fazer nenhum armazenamento em cache e usar CDNs para aproximar o conteúdo dos usuários. Toda vez que um usuário carrega seu site, ele vai para a rede para ver se está atualizado. Essa solicitação terá baixa latência, porque será fornecida por uma CDN geograficamente próxima a cada usuário final.
É possível configurar seu host da Web para responder a solicitações da Web com este cabeçalho:
Cache-Control: max-age=0,must-revalidate,public
Isso basicamente significa que o arquivo não é válido por nenhum período e precisa ser validado pela rede antes de ser usado novamente. Caso contrário, ele será apenas "sugerido".
Esse processo de validação é relativamente barato em termos de bytes transferidos. Se um arquivo de imagem grande não tiver sido alterado, o navegador receberá uma pequena resposta 304, mas custa latência, porque o usuário ainda precisará acessar a rede para descobrir. Essa é a principal desvantagem dessa abordagem. Ele pode funcionar muito bem para pessoas com conexões rápidas no mundo desenvolvido e onde a CDN escolhida tem ótima cobertura, mas não para pessoas que podem estar em conexões móveis mais lentas ou usando infraestrutura precária.
De qualquer forma, essa é uma abordagem moderna que é o padrão em um CDN conhecido, o Netlify, mas pode ser configurada em quase qualquer CDN. No Firebase Hosting, é possível incluir este cabeçalho na seção de hospedagem do arquivo firebase.json:
"headers": [
// Be sure to put this last, to not override other headers
{
"source": "**",
"headers": [ {
"key": "Cache-Control",
"value": "max-age=0,must-revalidate,public"
}
}
]
Eu ainda sugiro esse padrão, mas é apenas esse... o padrão. Continue lendo para saber como fazer upgrade dos padrões.
URLs com impressão digital
Ao incluir um hash do conteúdo do arquivo no nome de recursos, imagens e assim
por diante no site, você garante que esses arquivos sempre terão conteúdo
exclusivo. Isso resultará em arquivos com o nome sitecode.af12de.js
, por exemplo. Quando
o servidor responder às solicitações desses arquivos, você poderá instruir com segurança os
navegadores do usuário final para armazenar em cache por um longo período, configurando-os com este
cabeçalho:
Cache-Control: max-age=31536000,immutable
Esse valor é um ano, em segundos. De acordo com a especificação, isso é igual a "para sempre".
Não gere esses hashes manualmente, é muito trabalho manual. Você pode usar ferramentas como Webpack, Rollup e assim por diante para ajudar com isso. Leia mais sobre isso no Relatório de ferramentas.
Não é apenas o JavaScript que pode se beneficiar de URLs com impressão digital. Recursos como ícones, CSS e outros arquivos de dados imutáveis também podem ser nomeados dessa forma. Assista ao vídeo acima para saber mais sobre a divisão de código, que permite enviar menos código sempre que o site muda.
Independentemente de como o site aborda o armazenamento em cache, esses tipos de arquivos com impressão digital são extremamente valiosos para qualquer site que você possa criar. A maioria dos sites não muda em todas as versões.
É claro que não podemos renomear nossas páginas "amigáveis" voltadas ao usuário dessa maneira: renomeie
o arquivo index.html
para index.abcd12.html
. Isso é inviável, não é possível pedir
aos usuários para acessar um novo URL sempre que eles carregam seu site. Esses URLs "amigáveis" não podem ser renomeados e armazenados em cache dessa maneira, o que me leva a um possível meio-termo.
O meio-termo
Obviamente, há um meio termo quando se trata de armazenamento em cache. Apresentei duas opções extremas: cache nunca ou cache para sempre. E haverá um número de arquivos que você poderá armazenar em cache por um tempo, como os URLs "amigáveis" que mencionei acima.
Se você quiser armazenar em cache esses URLs "amigáveis" e o HTML deles, vale a pena considerar quais dependências eles incluem, como eles podem ser armazenados em cache e como o armazenamento em cache dos URLs por um tempo pode afetar você. Vamos analisar uma página HTML que inclui uma imagem como esta:
<img src="/images/foo.jpeg" loading="lazy" />
Se você atualizar ou alterar seu site excluindo ou alterando essa imagem
com carregamento lento, os usuários que visualizarem uma versão em cache do HTML poderão receber uma imagem incorreta ou
ausente porque ainda armazenaram em cache o /images/foo.jpeg
original quando
voltaram ao site.
Se você tomar cuidado, isso não vai afetar você. Mas, de modo geral, é importante lembrar que o site, quando armazenado em cache pelos usuários finais, não existe mais apenas nos seus servidores. Em vez disso, ele pode existir em partes nos caches dos navegadores do usuário final.
Em geral, a maioria dos guias sobre armazenamento em cache fala sobre esse tipo de configuração: se você quer armazenar em cache por uma hora, várias horas e assim por diante. Para definir esse tipo de cache, use um cabeçalho como este (que armazena em cache por 3600 segundos ou uma hora):
Cache-Control: max-age=3600,immutable,public
Um último ponto. Se você estiver criando conteúdo oportuno que normalmente só pode ser acessado pelos usuários uma vez, como artigos de notícias, minha opinião é que eles nunca devem ser armazenados em cache, e você deve usar o padrão sensato acima. Muitas vezes, superestimamos o valor do armazenamento em cache em vez do desejo do usuário de sempre conferir o melhor e mais recente conteúdo, como uma atualização crítica de uma notícia ou evento atual.
Opções que não são HTML
Além do HTML, algumas outras opções para arquivos que ficam no meio-termo incluem:
Em geral, procure recursos que não afetem outros
- Por exemplo: evite o CSS, porque ele causa mudanças na forma como o HTML é renderizado.
Imagens grandes usadas em artigos oportunos
- Os usuários provavelmente não vão visitar um único artigo mais do que algumas vezes. Portanto, não armazene fotos ou imagens principais em cache para sempre e gaste armazenamento.
Um recurso que representa algo que tem vida útil
- Os dados JSON sobre o clima podem ser publicados apenas a cada hora. Portanto, armazene em cache o resultado anterior por uma hora. Ele não vai mudar na janela
- Os builds de um projeto de código aberto podem ser limitados por taxa, portanto, armazene em cache uma imagem de status da versão até que seja possível que o status mude
Resumo
Quando os usuários carregam seu site pela segunda vez, você já tem um voto de confiança: eles querem voltar e receber mais do que você oferece. Nesse momento, não se trata apenas de reduzir o tempo de carregamento. Você tem várias opções disponíveis para garantir que o navegador faça apenas o trabalho necessário para oferecer uma experiência rápida e atualizada.
O armazenamento em cache não é um conceito novo na Web, mas talvez precise de um padrão padrão. Considere usar um e ative as melhores estratégias de armazenamento em cache quando precisar. Agradecemos por ler.
Consulte também
Para um guia geral sobre o cache HTTP, consulte Impedir solicitações de rede desnecessárias com o cache HTTP.