Compactar com GZip e armazenar em Cache arquivos .js e .css (solução)

Editado:

Pessoal, para a melhor solução para este tipo de problema vejam a regra número 4 deste post.
Se quizer entender mais sobre GZip continue lendo.

Fim da edição.

GZip é uma compactação feita pelo servidor web antes de enviar os arquivos para o browser, mas para que isso ocorra com sucesso deve-se mudar o cabeçalho dos arquivos para indicar que o arquivo aceita esse tipo de compactação, para que o servidor compacte este arquivo e quando esse arquivo chegar no browser, este descompacte-o, tornando-o um arquivo normal como todos os outros novamente.

A motivo de informação sobre os benefícios da compactação GZip darei um exemplo de uma biblioteca muito famosa, a JQuery, que tem em torno de 77kb em sua forma normal. Se for usado o compactador de javascript do Yahoo! ele passa a ter em torno de 46kb, e se for usada a compactação GZip em cima desse arquivo a biblioteca fica com incríveis 15kb!

Vinha a um tempo pensando em uma forma inteligente de compactar arquivos “.js” e “.css” usando GZip. Li vários artigos no Yahoo! e em fórums diversos e não encontrei nada falando a respeito, e quando falavam não era de forma clara, tanto é que só fui ver uma forma inteligente de se fazer isso a uns minutos atrás, quando achei algo a respeito no site do Joomla. É uma extensão que modifica o cabeçalho dos arquivos que são incluídos nas páginas desse sistema. Vendo a extensão eu pude ver o quão simples é modificar o cabeçalho de arquivos .css e .js de forma inteligente. Antes havia pensado em modificar a extensão dos arquivos para “.php” e fazer essas modificações (trabalho de corno), vi que funcionou mas não era viável em um projeto grande.

Bom, falei demais já. Vamos para o código da solução:

  /**
* @author Fábio Miranda Costa  
* Usado para compactar arquivos JS e CSS, acrescenta-os ao cache do browser
* e faz algumas melhorias adicionais. 
*/
$file = $_GET[”file”];
$ext = substr($file,strrpos($file, “.”)+1,strlen($file));
ob_start (”ob_gzhandler”);
if($ext==”js”) $ext=”javascript”;
header( “Content-type: text/”.$ext.”; charset: iso-8859-1“);//não se esqueça de mudar para o charset que você usa
header( “Content-Encoding: gzip,deflate”);
header( “Expires: “.gmdate(”D, d M Y H:i:s”, time() + (24 * 60 * 60)) . ” GMT”);//adiciona 1 dia ao tempo de expiração
header( “ETag: “);//a idéia é apagar o conteúdo da Etag, ver post http://www.meiocodigo.com/2007/12/21/melhorando-o-tempo-de-carregamento-de-um-site/
header( “Cache-Control: must-revalidate, proxy-revalidate” );
include($file);
ob_flush();

Fiz esse código o mais compacto possível, já que será usado em todos os includes de css e js do site.
Não vou explicar muito como funciona, apenas como usá-lo, que é o que importa.
Para usar é muito fácil, apenas crie um arquivos incluindo o código acima, no meu exemplo o arquivo é “file_inc.php”, e coloque no cabeçalho do seu site os includes de arquivos css e javascript seguindo os exemplos abaixo:

para javascript:

<script src="incs/file_inc.php?file=funcs.js" type="text/javascript"></script>

No atributo “src” coloque o caminho para o arquivo “file_inc.php” depois passe a variável “file” usando GET, ou seja adicione o texto “?file=” logo após o nome do arquivo, como pode-se ver no exemplo e depois coloque o endereço do arquivo “.js” que você quer incluir em seu site. Lembrando que esse endereço será sempre relativo ao arquivos file_inc.php, ou seja, se o “file_inc.php” estiver na pasta “inc/includer/” e o arquivo que você quer incluir está na pasta “inc/js/” o “src” do include ficará “inc/includer/file_inc.php?file=../js/funcs.js”.

para css:

<link href="incs/file_inc.php?file=styles.css" rel="stylesheet" type="text/css" />

Com o css é a mesma coisa, o que muda é apenas o óbvio, ou seja, a tag será “link” e o atributo usado passará a ser “href”.

15 Responses to “Compactar com GZip e armazenar em Cache arquivos .js e .css (solução)”

  1. Henrique Says:

    Cara, cada vez mais inteligente e útil o conteúdo do seu blog. Parabéns!

  2. eWil Says:

    Descobri que podia compactar em gzip lendo o conteúdo desse blog.

    Curiosamente continuei pesquisando sobre e existe um outro método de fazer isso, do qual compacta todo o código fonte também e não só os includes js e css!

    Nesse site dá pra verificar se o site é compactado ou não, a taxa de compressão e o tamanho original/compactado do arquivo!
    http://www.gidnetwork.com/tools/gzip-test.php

    Basta adicionar ao topo da página antes de qualquer coisa: ob_start(”ob_gzhandler”);

    Feito isso o HTML e todos includes virão como gzip!

  3. eWil Says:

    No ultimo post me enganei em dizer que tudo o que ele puxar externo será em gzip, fazendo alguns testes descobri que é apenas o HTML mesmo.

    Mas fica aí a dica, se o código html for um tanto extenso é mais um meio de diminuir a transferência e aumentar a velocidade do site ;)

  4. meiocodigo Says:

    A forma mais fácil de compactar usando gZip na minha opinião se encontra no último post desse blog, quando se fala sobre compactação gZip.
    você só precisa criar um arquivo .htaccess na pasta root do seu site e colocar a seguinte linha para que todos os arquivos javascript e css sejam compactados.


    AddOutputFilterByType DEFLATE application/x-javascript text/css text/javascript

    Para compactar o código fonte também é só adicionar o mime type text/html.
    Isso só funciona em servidores apache com mod_deflate instalado e que aceitem arquivos .htaccess além de que a diretiva allowOverride deve ter valor All ou pelo menos aceitar o deflate. O dreamhost, por exemplo, tem todos esses pré requisitos.

    abraço.

  5. Flávio Says:

    eu consegui o gzip assim, no arquivo .htaccess no diretorio raiz do site:

    SetOutputFilter DEFLATE

    o modulo deflate deve estar carregado

  6. anselmo Says:

    Como eu posso saber se o .htaccess ta fazendo efeito e os arquivos realmente estão sendo compactados ?

  7. meiocodigo Says:

    Olá anselmo,
    No meu caso para saber se a compatação está realmente funcionando eu use o plugin do firefox, firebug (www.getfirebug.com). Nele existe a aba NET onde você pode verificar quais os arquivos que estão sendo carregados pelo site. Como você sabe o tamanho original do arquivo, se ele mostrar um tamanho inferior ao normal é porque o arquivo foi compactado.
    Espero ter ajudado.

  8. Gaido Says:

    Você pode nos mostrar testes de desempenho de carregamento utilizando essa parafernália?

  9. fabio Says:

    amigo, veja o próximo post e veja a regra número 4.

    http://www.meiocodigo.com/2007/12/21/melhorando-o-tempo-de-carregamento-de-um-site/

    Esse método citado aqui com um arquivo php para incluir outros arquivos não é o mais prático, o mais prático é usando um .htaccess e você pode ver instruções para isso neste link que eu passei.

    Obrigado pelo comentário.

  10. Rodrigo Emanuel Says:

    Bom, testei muito e não funcionou (PHP 5.2.5) … não sei se é porque rodo apache + php no windows … mas enfim …

    Então, depois de dar uma lida, fiz a seguinte modificação no seu código:

    na linha onde tem: ob_start (”ob_gz”); …
    alterei para ob_start (”ob_gzhandler”);

    E funcionou … compactação extraordinária … compactou meu JS em quase 70% … realmente … ;D

  11. fabiomcosta Says:

    ok amigo, muito obrigado pela colaboração.
    Já editei o post.
    Mais uma vez peço para que verifique a regra número 4 do post http://www.meiocodigo.com/2007/12/21/melhorando-o-tempo-de-carregamento-de-um-site/
    Abraço.

  12. Edinho Says:

    A compressão é compatível com todos os Browsers ?

  13. fabiomcosta Says:

    Sim edinho, todos os browsers mais novos são compatíveis com a compactação gzip.

    No link a seguir você pode ver os browsers que não suportam:
    http://schroepl.net/projekte/mod_gzip/browser.htm

  14. Luiz Fernando Says:

    Da onde que vem as variaveis $file_last_modified e $maxage

    ???

  15. fabiomcosta Says:

    Desculpe amigo, havia feito algumas atualizações neste código recentemente e esqueci de remover estas variáveis.
    Obrigado pela lembrança.
    Post atualizado.

Leave a Reply