Um problema no desenvolvimento de aplicações web é o cache do navegador. É muito comum situações nas quais alteramos arquivos CSS em nosso projeto, enviamos a aplicação para o ambiente de produção e mesmo assim nossos clientes continuam vendo o layout da versão anterior. Isto ocorre porquê o browser cacheia os arquivos baixados da Internet para melhorar a performance de navegação.
Há duas soluções para este problema: uma porca e outra elegante. A porca é pedir a seus clientes que esvaziem o cache do navegador, expondo assim a sua incompetência e queimando seu filme. A elegante é tirar proveito do número de versão do seu projeto.
CSS – evitando o cache
A técnica é bastante simples: o navegador identifica os recursos cacheados pela URL que usou para acessá-los. A solução para quem programa em Grails é composta de apenas dois passos.
1. Altere a versão da sua aplicação
Na raiz do seu projeto Grails há um arquivo chamado application.properties. É nele que ficam armazenadas meta-informações sobre sua aplicação, como por exemplo a versão do Grails e do seu projeto. A chave app.version contém este valor. Novamente, há três modos de alterar esta configuração. Uma é horrível, a feia e a terceira, a prática.
Opção horrível: altere o arquivo manualmente. Busque a chave application.properties e a altere de acordo com sua vontade.
Opção feia: use o comando grails set-version. É um script do Grails feito especificamente para esta tarefa.
O problema com as duas opções acima é que exigem que você, desenvolvedor, se lembre de executar estes passos. Por esta razão, recomendo a opção prática: interceptar o evento de compilação do seu projeto.
Opção prática
Você deverá incluir um evento no script de compilação do seu projeto. Isto é feito criando-se o arquivo _Events.groovy dentro do diretório scripts da sua aplicação. Toda vez que o seu código for compilado pelo Grails, ele buscará este arquivo que pode conter uma série de eventos a serem disparados pelo mecanismo de build do Framework (neste link há mais detalhes sobre este poderoso recurso).
Sem mais esperas, segue o evento que escrevi que deverá ser executado antes da compilação do projeto:
eventCompileStart = { kind -> println "Incrementando o número da versão" def versao = metadata.'app.version' if (!versao) versao = 0 else versao = Double.valueOf(versao) + 0.01 metadata.'app.version' = versao.toString() try { metadata.persist() println "Versão alterada para ${versao}" } catch (Exception ex) { ex.printStackTrace() } println "Nova versão: ${versao}" }
(nota: o número de versão neste exemplo será algo horrível como 0.01000000003. A idéia do post é só passar a idéia básica ok? Sendo assim, lembre-se de “embelezar” seu número de versão)
2. Modificando a URL dos seus arquivos CSS
Esta é a parte fácil, e pode ser aplicada a qualquer recurso que sofra alterações entre uma versão e outra do seu projeto. Basta incluir o número da versão após o caractere ? na URL que identifica o seu arquivo CSS, tal como no exemplo abaixo.
<link rel="stylesheet" href="${resource(dir:'css',file:'main.css')}?${grailsApplication.metadata['app.version']}" />
O caractere “?” é usado para separar o nome do recurso dos parâmetros a serem passados ao servidor. Como se trata de um arquivo estático, o servidor irá ignorar os parâmetros passados e simplesmente retornar o arquivo. O navegador, por sua vez, irá cachear o arquivo CSS com um nome que varia de acordo com a versão do seu projeto, evitando assim o problema de cache que mencionei acima.
Ajax – como evitar problemas com o maldito cache
Em aplicações que acessem dados alterados com frequência, é muito comum o navegador (especialmente o Internet Explorer, cuja principal função é tornar sua vida um inferno) retornar dados cacheados ao navegador, ao invés das informações mais atualizadas. Neste caso, a solução é basicamente a mesma que apresentei para os arquivos CSS. Basta incluir um parâmetro a mais na sua requisição assíncrona que seja randômico.
Assim o navegador sempre acreditará estar buscando um novo recurso, mesmo que o resultado seja o mesmo. Abaixo segue um exemplo usando jQuery.
$("#elemento").load("/aplicacao/controlador/action", {produto:idProduto, colaborador: idColaborador, noCache:new Date()}, function() { onChangePreAtividade() })
Repare que passo um atributo chamado noCache. Meu controlador simplesmente irá ignorá-lo. No caso, eu passei apenas uma nova instância da hora da requisição, representada pelo objeto Date. Mas poderia também usar Math.random() para obter o mesmo resultado.
Concluindo
É isto. Agora você pode respirar tranquilo tendo a certeza de que seus usuários sempre terão uma resposta Ajax atualizada e o CSS mais atual carregado em seu navegador. Até a próxima!
Deixe uma resposta