A busca de recursos na rede é lenta e cara:
- Respostas grandes exigem muitas idas e voltas entre o navegador e o servidor.
- Sua página não carregará até que o download de todos os recursos críticos seja concluído.
- Se uma pessoa acessar seu site com um plano limitado de dados móveis, todas as solicitações de rede desnecessárias serão um desperdício do dinheiro.
Como evitar solicitações de rede desnecessárias? O cache HTTP do navegador é sua primeira linha de defesa. Não é necessariamente a abordagem mais eficiente ou flexível, e você tem controle limitado sobre o ciclo de vida das respostas em cache, mas ela é eficaz, compatível com todos os navegadores e não exige muito trabalho.
Este guia mostra os fundamentos de uma implementação eficaz do armazenamento em cache HTTP.
Compatibilidade com navegadores
Na verdade, não há uma única API chamada cache HTTP. É o nome geral de uma coleção de APIs de plataforma da Web. Essas APIs são compatíveis com todos os navegadores:
Como funciona o cache HTTP
Todas as solicitações HTTP feitas pelo navegador são primeiro roteadas ao cache do navegador para verificar se há uma resposta válida armazenada em cache que possa ser usada para atender à solicitação. Se houver uma correspondência, a resposta será lida do cache, o que elimina a latência da rede e os custos de dados em que a transferência incorre.
O comportamento do cache HTTP é controlado por uma combinação de cabeçalhos de solicitação e cabeçalhos de resposta. Em um cenário ideal, você terá controle sobre o código do aplicativo da Web (que determinará os cabeçalhos da solicitação) e a configuração do servidor da Web (que determinará os cabeçalhos de resposta).
Confira o artigo Armazenamento em cache de HTTP da MDN para ter uma visão geral conceitual mais aprofundada.
Cabeçalhos de solicitação: manter os padrões (geralmente)
Embora existam vários cabeçalhos importantes que precisam ser incluídos nas
solicitações de saída do seu app da Web, o navegador quase sempre os configura
por você ao fazer solicitações. Os cabeçalhos de solicitação que afetam a verificação
de atualização, como If-None-Match
e
If-Modified-Since
, aparecem de acordo com o entendimento do navegador
sobre os valores atuais no cache HTTP.
Isso é uma boa notícia. Isso significa que você pode continuar incluindo tags como <img
src="my-image.png">
no seu HTML, e o navegador cuida automaticamente do
armazenamento em cache do HTTP para você, sem esforço extra.
Cabeçalhos de resposta: configurar seu servidor da Web
A parte da configuração do armazenamento em cache HTTP que mais importa são os cabeçalhos que seu servidor da Web adiciona a cada resposta de saída. Os cabeçalhos a seguir influenciam o comportamento eficaz do armazenamento em cache:
Cache-Control
. O servidor pode retornar uma diretivaCache-Control
para especificar como e por quanto tempo o navegador e outros caches intermediários armazenarão a resposta individual em cache.ETag
. Quando o navegador encontra uma resposta expirada em cache, ele pode enviar um pequeno token (geralmente um hash do conteúdo do arquivo) ao servidor para verificar se o arquivo foi alterado. Se o servidor retornar o mesmo token, o arquivo será o mesmo e não será necessário fazer o download novamente.Last-Modified
. Esse cabeçalho tem a mesma finalidade queETag
, mas usa uma estratégia baseada em tempo para determinar se um recurso mudou, em vez da estratégia baseada em conteúdo deETag
.
Alguns servidores da Web oferecem suporte integrado para definir esses cabeçalhos por padrão, enquanto outros deixam os cabeçalhos totalmente de fora, a menos que você os configure explicitamente. Os detalhes específicos de como configurar cabeçalhos variam muito dependendo do servidor da Web usado. Consulte a documentação do seu servidor para ver os detalhes mais precisos.
Para economizar um pouco de pesquisa, veja aqui instruções sobre como configurar alguns servidores da Web conhecidos:
- Express
- Apache
- nginx
- Firebase Hosting
- Netlify (em inglês)
Deixar de fora o cabeçalho de resposta Cache-Control
não desativa o armazenamento em cache HTTP.
Em vez disso, os navegadores adivinham
efetivamente
que tipo de comportamento de armazenamento em cache faz mais sentido para determinado tipo de conteúdo.
É provável que você queira mais controle do que isso oferece, então reserve um tempo para configurar os cabeçalhos de resposta.
Quais valores de cabeçalho de resposta você deve usar?
Há dois cenários importantes que precisam ser considerados ao configurar os cabeçalhos de resposta do servidor da Web.
Armazenamento em cache de longa duração para URLs com controle de versão
Suponha que seu servidor instrua os navegadores a armazenar um arquivo CSS em cache por 1 ano (Cache-Control: max-age=31536000
), mas seu designer acabou de fazer uma atualização de emergência que você precisa implementar imediatamente. Como notificar os navegadores
para atualizar a cópia em cache "desatualizada" do arquivo?
Não é possível, pelo menos não sem alterar o URL do recurso. Depois que o
navegador armazena a resposta em cache, a versão em cache é usada até que não esteja mais
atualizada, conforme determinado por max-age
ou expires
, ou até que seja removida do cache
por algum outro motivo. Por exemplo, quando o usuário limpa o cache do navegador. Como
resultado, usuários diferentes podem acabar usando versões diferentes do arquivo quando
a página é criada: os que acabaram de buscar o recurso usam a nova
versão, enquanto os que armazenaram em cache uma cópia anterior (mas ainda válida) usam uma versão
mais antiga da resposta. Como você pode aproveitar o melhor das duas opções: armazenamento em cache
do lado do cliente e atualizações rápidas? Você altera o URL do recurso e força o usuário a fazer o download da nova resposta sempre que o conteúdo é alterado. Normalmente, isso é feito incorporando uma impressão digital do arquivo, ou um número de versão, no nome de arquivo, por exemplo, style.x234dff.css
.
Ao responder a solicitações de URLs com informações de
"impressão digital" ou
de controle de versão, com conteúdos que nunca vão mudar, adicione
Cache-Control: max-age=31536000
às respostas.
A definição desse valor informa ao navegador que,quando precisar carregar o mesmo URL a qualquer momento durante o próximo ano (31.536.000 segundos,o valor máximo aceito), ele poderá usar imediatamente o valor no cache HTTP, sem precisar fazer uma solicitação de rede ao servidor da Web. Excelente! Você ganhou imediatamente a confiabilidade e a velocidade de evitar a rede.
Ferramentas de criação como o webpack podem automatizar o processo de atribuição de impressões digitais hash aos URLs de recursos.
Revalidação do servidor para URLs sem controle de versão
Infelizmente, nem todos os URLs que você carrega têm controle de versão. Talvez você não possa
incluir uma etapa de versão antes da implantação do app da Web para não poder adicionar hashes
aos URLs de recurso. E todos os aplicativos da Web precisam de arquivos HTML. Esses arquivos
(quase!) nunca vão incluir informações de controle de versão, já que ninguém
vai precisar usar seu app da Web se precisar lembrar que o URL a ser acessado é
https://example.com/index.34def12.html
. O que você pode fazer com esses URLs?
Este é um cenário em que você precisa admitir a derrota. O armazenamento em cache HTTP por si só não é potencial o suficiente para evitar a rede por completo. Não se preocupe, em breve você aprenderá sobre os service workers, que fornecerão o suporte necessário para levar a batalha a seu favor. Mas há algumas etapas que você pode seguir para garantir que as solicitações de rede sejam as mais rápidas e eficientes possível.
Os valores Cache-Control
a seguir podem ajudar você a ajustar onde e como os URLs sem controle de versão
são armazenados em cache:
no-cache
. Isso instrui o navegador a revalidar com o servidor todas as vezes antes de usar uma versão em cache do URL.no-store
. Isso instrui o navegador e outros caches intermediários (como CDNs) a nunca armazenar nenhuma versão do arquivo.private
: os navegadores podem armazenar o arquivo em cache, mas os caches intermediários não.public
. A resposta pode ser armazenada por qualquer cache.
Confira o Apêndice: fluxograma de Cache-Control
para visualizar o processo
de decisão de quais valores de Cache-Control
usar. Observe também que Cache-Control
pode
aceitar uma lista de diretivas separadas por vírgulas. Consulte o Apêndice: exemplos de Cache-Control
.
Além disso, a configuração de um dos dois cabeçalhos de resposta adicionais também pode ajudar:
ETag
ou Last-Modified
. Conforme mencionado em
Cabeçalhos de resposta, ETag
e Last-Modified
têm a
mesma finalidade: determinar se o navegador precisa fazer o download novamente de um arquivo armazenado
em cache que expirou. ETag
é a abordagem recomendada porque é mais precisa.
Suponha que tenham se passado 120 segundos desde a busca inicial e o navegador
iniciou uma nova solicitação para o mesmo recurso. Primeiro, o navegador verifica o cache HTTP e encontra a resposta anterior. O navegador não pode usar a resposta anterior porque ela expirou. Nesse ponto, o navegador pode enviar uma nova solicitação e buscar a nova resposta completa. No entanto, isso não é eficiente porque, se o recurso não foi alterado,
não há motivo para fazer o download das mesmas informações que já estão no
cache. Esse é o problema que os tokens de validação, conforme especificado no cabeçalho
ETag
, são projetados para resolver. O servidor gera e retorna um token arbitrário, que normalmente é um hash ou outra impressão digital do conteúdo do arquivo. O navegador não precisa saber como a impressão digital é gerada. Ele só precisa enviá-la ao servidor na próxima solicitação. Se a impressão digital ainda for a mesma, isso significa que o recurso não foi alterado e o navegador pode ignorar o download.
Ao definir ETag
ou Last-Modified
, a
solicitação de revalidação fica muito mais eficiente. Elas acabam acionando os cabeçalhos de solicitação
If-Modified-Since
ou If-None-Match
mencionados em Cabeçalhos de solicitação.
Quando um servidor da Web configurado corretamente vê esses cabeçalhos de solicitação de entrada, ele pode confirmar se a versão do recurso que o navegador já tem no cache HTTP corresponde à versão mais recente no servidor da Web. Se houver uma correspondência,
o servidor poderá responder com uma resposta HTTP 304 Not Modified
,
que é equivalente a "Ei, continue usando o que você já tem!" Há muito poucos dados para transferir ao enviar esse tipo de resposta. Por isso, o processo geralmente é muito mais rápido do que o envio de uma cópia do recurso que está sendo solicitado.

/file
do servidor e inclui o cabeçalho If-None-Match
para instruir o servidor a retornar o arquivo completo somente se o ETag
dele não corresponder ao valor If-None-Match
do navegador. Nesse
caso, os dois valores foram correspondentes, então o servidor retorna uma resposta 304 Not Modified
com instruções sobre por quanto tempo o arquivo precisa ser armazenado em cache (Cache-Control: max-age=120
).
Resumo
O cache HTTP é uma maneira eficaz de melhorar o desempenho do carregamento, porque reduz solicitações de rede desnecessárias. Ele pode ser usado em todos os navegadores e não tem muito trabalho para configurar.
As seguintes configurações de Cache-Control
são um bom começo:
Cache-Control: no-cache
para recursos que precisam ser revalidados com o servidor antes de cada uso.Cache-Control: no-store
para recursos que nunca podem ser armazenados em cache.Cache-Control: max-age=31536000
para recursos com controle de versão.
Além disso, os cabeçalhos ETag
ou Last-Modified
podem ajudar a revalidar recursos de cache expirados com mais eficiência.
Saiba mais
Se você quiser ir além do básico do uso do cabeçalho Cache-Control
,
consulte o guia Práticas recomendadas de armazenamento em cache e gotchas
max-age de Jake Archibald.
Consulte Ame seu cache para receber orientações sobre como otimizar o uso do cache para visitantes recorrentes.
Apêndice: mais dicas
Se você tiver mais tempo, veja outras maneiras de otimizar o uso do cache HTTP:
- Use URLs consistentes. Se o mesmo conteúdo for exibido em URLs diferentes, esse conteúdo será buscado e armazenado várias vezes.
- Diminua a desistência de usuários. Se parte de um recurso (como um arquivo CSS) for atualizada com frequência, enquanto o restante do arquivo não (como o código da biblioteca), divida esse código em um arquivo separado e use uma estratégia de armazenamento em cache de curta duração para o código atualizado com frequência e uma estratégia de longa duração de armazenamento em cache para o código que não muda com frequência.
- Confira a nova diretiva
stale-while-revalidate
se algum grau de inatividade for aceitável na sua políticaCache-Control
.
Apêndice: fluxograma do Cache-Control
Apêndice: exemplos de Cache-Control
Valor Cache-Control |
Explicação |
---|---|
max-age=86400 |
A resposta pode ser armazenada em cache por navegadores e caches intermediários por até um dia (60 segundos x 60 minutos x 24 horas). |
private, max-age=600 |
A resposta pode ser armazenada em cache pelo navegador (mas não por caches intermediários) por até 10 minutos (60 segundos x 10 minutos). |
public, max-age=31536000 |
A resposta pode ser armazenada por qualquer cache por um ano. |
no-store |
A resposta não pode ser armazenada em cache e precisa ser buscada na íntegra em cada solicitação. |