Amo seu cache ❤️

Os usuários que carregarem seu site pela segunda vez usarão o cache HTTP. Por isso, verifique se funciona bem.

Esta postagem é um complemento do vídeo Love your cache, parte da série Conteúdo no Chrome Dev Summit 2020. Não deixe de conferir o vídeo:

Quando os usuários carregarem seu site pela segunda vez, o navegador deles usará recursos dentro e o cache HTTP dele para agilizar o carregamento. Mas os padrões de armazenamento em cache que remontam a 1999 e são definidas de modo bastante amplo, determinando se um arquivo, como CSS ou imagem, pode ser buscado novamente na rede e carregar do cache, não é uma ciência exata.

Nesta postagem, falarei sobre um padrão básico e moderno para armazenamento em cache, que realmente não armazena em cache. Mas esse é só o padrão, e é de mais nuances do que apenas "desligar". Siga em frente com a leitura.

Metas

Quando um site é carregado pela segunda vez, você tem duas metas:

  1. Certifique-se de que seus usuários tenham acesso à versão mais atualizada disponível, se você fez alguma alteração, isso será refletido rapidamente
  2. Faça a primeira ação buscando o mínimo possível na rede

No sentido mais amplo, você quer enviar somente a menor alteração aos seus clientes quando eles carregarem o site novamente. E estruturar seu site para garantir a maior a distribuição eficiente de qualquer mudança é um desafio (mais sobre isso abaixo e vídeo).

Dito isso, você também tem outros botões quando considera o armazenamento em cache - talvez você decidiu permitir que o cache HTTP do navegador do usuário permaneça em seu site por um longo período tempo para que nenhuma solicitação de rede seja necessária para exibi-lo. Ou você criou um service worker que atenderá um site totalmente off-line antes verificando se estão atualizados. Essa é uma opção extrema, válida e usada para muitas experiências na Web baseadas em apps que priorizam o modo off-line, mas a Web não precisa ser em uma situação extrema somente em cache ou até mesmo em casos completamente exclusivos da rede.

Contexto

Como desenvolvedores Web, estamos todos acostumados com a ideia de ter um "cache obsoleto". Mas sabemos quase que instintivamente, as ferramentas disponíveis para resolver isso: fazer uma "tarefa atualizar", ou abrir uma janela anônima, ou usar alguma combinação de para desenvolvedores limpar os dados de um site.

Usuários comuns na Internet não têm o mesmo luxo. Portanto, embora têm algumas metas principais de garantir que os usuários aproveitem ao máximo carga, também é muito importante garantir que eles não tenham um momento ruim ou ficar preso. (Confira este vídeo se quiser me ouvir falar sobre como quase deixamos o site web.dev/live paralisado.)

Vamos entender um pouco melhor, um motivo muito comum para "cache obsoleto" é, na verdade, o padrão da era de 1999 para armazenamento em cache. Ela depende do cabeçalho Last-Modified:

Diagrama mostrando por quanto tempo diferentes recursos são armazenados em cache pelo navegador de um usuário
Os recursos gerados em momentos diferentes (em cinza) serão armazenados em cache por em momentos diferentes. Assim, um segundo carregamento pode ter uma combinação de recursos novos e em cache.

Cada arquivo carregado é mantido por mais 10% do tempo de vida útil atual, conforme seu navegador o vê. Por exemplo, se index.html tiver sido criado há um mês, ele será armazenado em cache pelo navegador por mais três dias.

Essa era uma ideia bem-intencionada na época, mas dada a integrada dos sites de hoje, esse comportamento padrão significa que é possível para que o usuário tenha arquivos criados para diferentes versões seu site (por exemplo, o JS do lançamento de terça-feira e o CSS do lançamento da 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 seu conteúdo aos usuários. Cada vez que um usuário carrega seu site, ele vai até a rede para verifique se estão atualizados. Essa solicitação terá baixa latência, fornecidos por uma CDN geograficamente próxima a cada usuário final.

Configure seu host da Web para responder a solicitações da Web com este cabeçalho:

Cache-Control: max-age=0,must-revalidate,public

Basicamente, ela diz: o arquivo é válido por nenhum tempo, e você deve validar da rede para poder usá-lo novamente (caso contrário, ele só precisa "sugerido").

Esse processo de validação é relativamente barato em termos de bytes transferidos. Se um arquivo de imagem grande não tenha sido alterado, o navegador receberá um erro 304 resposta, mas custa latência, porque o usuário ainda precisa acessar a rede para encontrar para fora. E esta é a principal desvantagem dessa abordagem. Pode funcionar muito bem para pessoas que têm conexões rápidas no primeiro mundo, e quando sua CDN de escolha ótima cobertura, mas não para pessoas que usam dispositivos móveis mais lentos. ou por uma infraestrutura ruim.

Independentemente disso, essa é uma abordagem moderna que é o padrão em uma CDN conhecida, o Netlify, mas pode ser configurado em praticamente qualquer CDN. Para o 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 intervir e atualizar os padrões.

URLs com impressão digital

Com a inclusão de um hash do conteúdo do arquivo no nome dos recursos, das imagens e assim por diante veiculados em seu site, você pode garantir que esses arquivos sempre tenham títulos exclusivos content. Isso resultará em arquivos com o nome sitecode.af12de.js, por exemplo. Quando seu servidor responder a solicitações para esses arquivos, você poderá instruir com segurança dos navegadores do usuário final armazená-los em cache por muito tempo, configurando-os com este cabeçalho:

Cache-Control: max-age=31536000,immutable

Esse valor é um ano, em segundos. De acordo com as especificações, igual a "sempre".

É importante ressaltar que não gere esses hashes manualmente. É muito trabalho manual. Você pode usar ferramentas como Webpack, Rollup e assim por diante para ajudar nisso. Confirme e leia mais sobre eles no Relatório de ferramentas.

Lembre-se de que os URLs com impressão digital não se beneficiam apenas do JavaScript. ativos como ícones, CSS e outros arquivos de dados imutáveis também podem ser nomeados como este de um jeito fácil. (Assista ao vídeo acima para aprender um pouco mais sobre código divisão, o que permite que você envie menos códigos sempre que seu site for alterado.

Independentemente de como seu site aborda o armazenamento em cache, esses tipos de técnicas são incrivelmente valiosos para qualquer site que você possa criar. A maioria dos sites só não mudam a cada versão.

Claro, não podemos renomear nossas páginas "amigáveis" voltadas ao usuário desta forma: renomeando seu arquivo index.html para index.abcd12.html. Isso é inviável, não é possível que os usuários acessem um novo URL sempre que carregarem seu site. Estes "amigáveis" URLs e não pode ser renomeado e armazenado em cache dessa forma, o que me leva a um possível meio chão.

O meio-termo

Obviamente, existe um meio termo quando se trata de armazenamento em cache. eu apresentou duas opções extremas: armazenar em cache nunca ou sempre; E haverá um número de arquivos que você pode querer armazenar em cache por um tempo, como "amigável" os URLs que mencionei acima.

Se quiser armazenar em cache esses arquivos os URLs e o HTML deles, é importante considerando as dependências incluídas, como elas podem ser armazenadas em cache e como armazenar em cache os URLs por um tempo pode afetar você. Vejamos uma página HTML que inclui uma imagem como esta:

<img src="/images/foo.jpeg" loading="lazy" />

Se você atualizar ou mudar seu site excluindo ou alterando a configuração os usuários que visualizarem uma versão em cache do seu HTML poderão receber uma mensagem imagem ausente, porque o /images/foo.jpeg original ainda está armazenado em cache quando quando visitarem seu site novamente.

Se tiver cuidado, isso pode não afetar você. Mas, amplamente, é importante lembre-se de que seu site, quando armazenado em cache pelos usuários finais, não existe apenas seus servidores. Em vez disso, pode existir em partes dentro dos caches de seu navegador navegadores da Web.

Em geral, a maioria dos guias sobre armazenamento em cache falará sobre esse tipo de Se quiser armazenar em cache por uma hora, várias horas etc. Para definir isso, uma espécie de armazenamento em cache, use um cabeçalho como este (que armazena em cache por 3.600 segundos, ou hora):

Cache-Control: max-age=3600,immutable,public

Um último ponto. Se você está criando conteúdo oportuno, que normalmente só pode ser acessados pelos usuários uma vez, como notícias! Minha opinião é que esses nunca devem armazenados em cache, e você deve usar o padrão racional acima. Muitas vezes, superestimar o valor do armazenamento em cache do que a vontade do usuário de sempre ver e o melhor conteúdo, como uma atualização crítica de uma notícia ou atual evento.

Opções não HTML

Além do HTML, há algumas outras opções para arquivos que ficam no meio-termo incluem:

  • Em geral, procure recursos que não afetam outras pessoas

    • Por exemplo: evite CSS, pois ele causa alterações na forma como seu HTML é renderizado
  • Imagens grandes usadas como parte de artigos oportunos

    • Seus usuários provavelmente não vão mais acessar nenhum artigo algumas vezes; portanto, não armazene fotos ou imagens principais em cache para sempre e armazenamento de resíduos
  • Recurso que representa algo que tem vida útil

    • Os dados JSON sobre o clima podem ser publicados apenas a cada hora, então você pode armazenar em cache o resultado anterior por uma hora. Ele não mudará na sua janela
    • Os builds de um projeto de código aberto podem ter limitação de taxa, por isso, armazene em cache imagem de status do build até que seja possível que o status mude

Resumo

Quando os usuários carregam seu site pela segunda vez, você já teve uma votação de confiança, já que eles querem voltar e receber mais do que você oferece. Neste não se trata apenas de reduzir o tempo de carregamento, várias opções disponíveis para garantir que seu navegador faça apenas o trabalho ele precisa oferecer uma experiência rápida e atualizada.

O armazenamento em cache não é um conceito novo na Web, mas talvez precise padrão—considere usar um e opte por estratégias melhores de armazenamento em cache quando precisar deles. Agradecemos por ler.

Consulte também

Para obter um guia geral sobre o cache HTTP, confira Evite solicitações de rede desnecessárias com o cache HTTP.