Evitando o cache no cliente

HTML e CSS nunca foram meu forte, eu sei o que preciso saber para sobreviver, já que trabalho com desenvolvimento web. Não da pra esperar que eu consiga montar uma apresentação fantástica usando HTML5 e CSS3 e ainda por cima pensando fortemente em semântica, organização e melhores práticas, fato!

Não estou aqui criticando HTML e CSS, eu entendo perfeitamente a importância de tudo isso, mas não posso negar que nunca me dediquei muito para aprende-las, até porque nunca tive a necessidade de ser o responsável por esse trabalho. Exatamente por isso eu aprendi algo babacamente simples esses dias, porém extremamente eficiente.

Imagine mudar o CSS, subir pra produção e o cliente simplesmente ver o seu site totalmente quebrado? Pior, mudar uma imagem (um banner ou qualquer outra imagem) e o cliente continuar recebendo a imagem antiga. Quem trabalha com sistemas web e nunca passou por isso?

É muito comum alterarmos qualquer coisa estática como CSS, imagens e até JavaScript e essas alterações não serem interpretadas pelo navegador. O jeito é limpar (ou desligar) o cache do navegador, dar uns 3 ou mais refreshs ou apelar pro CTRL+F5, isso é o que fazemos desenvolvendo. Mas e quando isso acontece em produção, vamos dizer pro usuário/cliente ‘limpar o cache’? Claro que não, temos que dar um jeito então do navegador do cliente reconhecer as alterações logo na primeira visita.

Isso ocorre pois o navegador faz cache local destes recursos e os utiliza quando julga ser a melhor opção. A mesma coisa ocorre com proxy de redes, que também podem fazer cache. O jeito para descartar esse cache é fazer algum malabarismo no servidor web, mas nem sempre isso é possível, então precisamos recorrer à aplicação, onde – geralmente – temos maior domínio.

O cache no navegador tem uma regra básica super simples: o nome do recurso estático. Se mudarmos o nome de um arquivo CSS ou imagem, por exemplo, não teremos problema algum com cache. Se você puder fazer isso na sua aplicação, ótimo, problema resolvido.

Mas se não puder, temos outra opção simples e eficiente, podemos anexar algum parâmetro falso no nome do recurso, por exemplo:

1
<link rel="stylesheet" type="text/css" href="/css/estilo.css" />

Ao atualizar propriedades desta folha de estilo as alterações não serão perceptíveis no navegador enquanto o cache (do navegador) não for atualizado. E isso ou o cliente faz explicitamente ou nós faremos por ele. Então, vamos fazer a nossa parte, vejam:

1
<link rel="stylesheet" type="text/css" href="/css/estilo.css?1" />

O simples parâmetro ?1 cuida disso pra nós. O navegador vai encarar que se trata de uma nova folha de estilos e fará o download do servidor, utilizando esta nova versão no lugar da que ele tem em cache, na próxima visita o ?1 não vai fazer mais nada, já que o navegador já tem a folha de estilo com o ?1 em cache. O parâmetro ?1 pode ser atualizado toda vez que for preciso fazer alguma alteração na folha de estilo, desta forma o cliente terá sempre a versão correta toda vez que ela for atualizada.

Outra saída é usar um parâmetro que nunca será o mesmo, por exemplo: usar a data completa (dia, mês, ano, hora, minuto e segundo). Só que isso fará com que o cliente faça o download do recurso no servidor toda vez que acessar o site, o que pode causar um grande tráfego no servidor, impactando diretamente na performance da sua aplicação. Num captcha faz sentido, mas em outros casos é bom pensar bastante antes.

É isso, dica simples e fácil (e talvez boba), mas que me salvou um dia desses.

19 respostas para “Evitando o cache no cliente”

  1. Pingback: Jeveaux
  2. Pingback: Rafael Ponte
  3. Pingback: Léo Hackin
  4. Pingback: Alessandro Dourado
  5. Pingback: Alberto Leal
  6. Pingback: topsy_top20k_pt
  7. Essas coisa são controladas pelos cabeçalhos do HTTP, o cliente pede sobre informações de um recurso da rede, pode ser um comando condicional de If-Modified-Since, que pode retorna o objeto caso ele fora modificado desde uma determinada data.

    Outro controle no HTTP é mandar uma resposta com um tempo para expiração do cache daquele recurso, para o browser não precisar perguntar toda hora se houveram modificações.

    Configure teu servidor web e o web cache dele corretamente para não precisar de gambiarras assim.

    Só lembrando que qdo for se dedicar para aprender sobre web, não aprenda somente sobre HTML, CSS, JS, coisas da camada de conteúdo, IP, TCP/UDP e HTTP também são muito necessários.

    Dê uma olhada:
    http://en.wikipedia.org/wiki/List_of_HTTP_headers

    1. Olá Bruno,

      De fato é uma gambiarra, bem feia ainda. Mas é muito eficiente.

      Sua observação é muito importante, eu não entrei nesses detalhes no post pois queria mostrar apenas como fazer essa “solução de contorno”. Eu acho que já tenho algum pouquinho de conhecimento sobre o protocolo HTTP, TCP/UDP e IP, mas não paro de estudar. O motivo desta solução gambiarra é que o Cache-Control não é suportado por todos os browsers e sistemas de caching, e usar o Expires pode não ser necessário e/ou aconselhado quando você necessita atualizar apenas um de muitos recursos, e o If-Modified-Since pode não ser viável se você não tiver permissão/autoridade para instalar o mod_expires no apache. Aí, nesses casos a gambiarrazinha vai te ajudar bastante.

      Suas dicas são muito importantes, acho que eu poderia ter explicado um pouco mais sobre os motivos de usar essa gambiarrazinha, mas agora você já o fez aqui nos comentários, então, muito obrigado =D

      Abraço,

  8. Pingback: Bruno Arueira
  9. De fato isso ajuda muito. Um exemplo comum no qual eu utilizo é no upload de imagem atualizado via jQuery, no qual ao se fazer um upload deve-se “injetar” via ajax a nova imagem na tag src passando um parâmetro como um new Date() para que a mesma seja trocada sempre.

    Dica muito útil. (:

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.