Como evitar cache de CSS e Javascript

Saudações!

O grande problema de todas as criaturas que fazem artigos sempre é tempo. Meu tempo se divide ultimamente em cozinhar e trabalhar, então os artigos no blog tem ficado escassos. Hoje vamos mais uma vez tentar mudar isso.

Cenário

Imagine a seguinte situação:
Seu site, com tudo funcional, em seu perfeito e equilibrado estado, precisa de uma alteração, um novo recurso, ou algo parecido. Para isso, você tem que alterar o seu CSS e seu Javascript. Até ai tudo bem, nada de mais, visto que é algo banal, alterações são banais (NOT!), mas alguns usuários assiduos não estão vendo essas alterações feitas no sistema. O que diabos está ocorrendo? Se chama cache.

Cache

Para os pouco iluminados, cache é mais ou menos como copiar uma música no teu computador para evitar de sempre ter que ir na prateleira buscar, mas aplicado a informática. No caso do CSS e do Javascript, ele guarda uma cópia desses arquivos na máquina do cliente. Quando esse cliente acessar o site novamente, ao invés de fazer o download do arquivo do site, ele usará o arquivo em cache, evitando consumo de banda para o cliente e para o site. Essa cópia tem uma data para expirar, mas em muitos casos, não podemos contar com todo esse tempo (e sorte).

Evitando o Cache

Agora que já sabemos o que é Cache e como nosso browser usa ele, vamos aplicar isso no nosso cenário inicial. A prática padrão para isso é concatenar na URL do CSS/JS uma string, vamos iniciar com uma declaração padrão de um CSS (pode ser um JS, mas vou  usar CSS para os testes):

<link rel="stylesheet" type="text/css" media="screen" href="main.css" />

Bom, se analisarmos usando alguma ferramenta (neste caso, o firebug), vamos ver que no primeiro acesso, ele faz o download do CSS, tudo normal, mas ao acessarmos pela segunda vez a mesma página, ele não faz novamente o download do CSS e sim carrega ele do cache. Hum, já era sabido que isso ia acontecer, mas dessa vez, vamos fazer com que ele recarregue o CSS, sem necessidade de limpar o cache:

<link rel="stylesheet" type="text/css" media="screen" href="main.css?nocache" />

Hey! Mas o CSS aceita parâmetros como PHP? 
Não, não aceita, nem cogite deixar esse tipo de pensamento alocado no cérebro. Ele não aceita parâmetros, mas ele aceita a adição de conteudo "como se fosse" um parâmetro.

Recarregamos a página e analisamos novamente. Que maravilha, ele fez novamente o download do CSS como queriamos! But wait! se fizermos isso mais uma vez, lá vem o cache novamente para atrapalhar. 

Isso acontece porque ao adicionarmos a string, ele vai procurar no cache um arquivo "main.css?cache" para o seu dominio e não vai encontrar, porque em cache estava o "main.css", mas na segunda vez, ele vai encontrar e usar o cache novamente.

E agora? Eu quero que ele recarregue o CSS sempre que o usuário acessar o site. Como vamos fazer isso? 

Aqui entra nosso amigo PHP para nos dar uma mão (poderia ser em qualquer linguagem decente de programação). O que vamos fazer é adicionar como "parâmetro" ao CSS um timestamp (da execução do script), usando a função time do PHP assim:

<link rel="stylesheet" type="text/css" media="screen" href="main.css?<?php echo time();?>" />

Dessa maneira, sempre que o o usuário acessar o site, ele vai recarregar o CSS e sempre ter a última versão.

Isso funciona, na maioria dos casos vai ser o suficiente, mas imaginem um site com milhares de acessos, cada usuário tendo que recarregar sempre o CSS/JS, o consumo de banda que isso geraria no servidor. That's not cool!

Evitando o Cache (menos nocivo)

Existe uma maneira menos nociva de evitar o cache, que é recarregar o CSS/JS somente quando ele tiver alguma alteração, mantendo o cache até quando for necessário recarregá-lo.

Para isso, precisamos descobrir a data de alteração do arquivo (lá vem o PHP de novo) e usarmos ele como "parâmetro":

<link rel="stylesheet" type="text/css" media="screen" href="main.css?<?php echo filemtime('main.css'); ?> />

Agora sim, ao invés de recarregar o CSS toda santa vez que o usuário acessar o site, isso é seletivo, somente quando há uma mudança no CSS, mudando o timestamp de alteração do arquivo, ele será recarregado, consumindo somente a banda necessária, no momento certo!

Não foi tão dificil assim, podem admitir :)

Ficamos por aqui, aguardem notícias!



Sem Posts Relacionados.

Categoria: Sem categoria
Tags: , ,

7 respostas a Como evitar cache de CSS e Javascript

  1. Pessoal, boa tarde!

    Henrique, bom artigo e boa iniciativa. É uma situação que venho tendo aqui no Goldmap, mas sua solução ainda não cobre todo o problema.

    Dê uma olhada nesses links que creio que pode ajudar na discussão.
    1) (Para o lucas stephanou no primeiro comentário) Esses mostram que Etags nem sempre são a melhor solução: http://www.mnot.net/blog/2007/08/07/etags e http://html5boilerplate.com/docs/htaccess/ (procure por ETag no texto)
    2) (O problema da sua solução Henrique) Esse aqui diz o pq de NÃO usar querystring para otimizar o cache: http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/
    3) E esse apresenta a solução mais robusta que encontrei até então: http://particletree.com/notebook/automatically-version-your-css-and-javascript-files/

    O que acham? Alguma ideia melhor?

    Um abraço.
    Renato Martins.

  2. Buenas Renato!

    Ultimamente eu venho utilizando a solução proposta no 3º link, adicionar um versionamento(timestamp) ao arquivo CSS e usando uma RewriteRule para ser acessado corretamente, eu vou escrever mais um post falando sobre essa “nova” solução, que pelo menos até o momento, parece ser a com menos falhas.

    Muito obrigado pelo comentário e por compartilhar os links

Deixe um Comentário

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>