<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ataraxia! &#187; otimização</title>
	<atom:link href="http://www.ataraxia.com.br/posts/tag/otimizacao/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ataraxia.com.br</link>
	<description>O estado da arte em TI</description>
	<lastBuildDate>Sun, 17 Jul 2011 21:36:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Otimização de sites com memcached</title>
		<link>http://www.ataraxia.com.br/posts/otimizacao-de-sites-com-memcached</link>
		<comments>http://www.ataraxia.com.br/posts/otimizacao-de-sites-com-memcached#comments</comments>
		<pubDate>Sat, 16 May 2009 16:01:32 +0000</pubDate>
		<dc:creator>Bruno Lustosa</dc:creator>
				<category><![CDATA[programação]]></category>
		<category><![CDATA[bd]]></category>
		<category><![CDATA[memoria]]></category>
		<category><![CDATA[otimização]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.ataraxia.com.br/?p=328</guid>
		<description><![CDATA[Um projeto muito interessante, e que pode ser usado pra aumentar drasticamente o desempenho de aplicativos web é o Memcached. Pela descrição do site do projeto, o &#8220;memcached é um sistema distribuído de alto desempenho para o cacheamento de objetos na memória, genérico por natureza, mas feito para se aumentar a velocidade de sites dinâmicos [...]]]></description>
			<content:encoded><![CDATA[<p>Um projeto muito interessante, e que pode ser usado pra aumentar drasticamente o desempenho de aplicativos web é o <a href="http://www.danga.com/memcached/">Memcached</a>. Pela descrição do site do projeto, o &#8220;memcached é um sistema distribuído de alto desempenho para o <i>cacheamento</i> de objetos na memória, genérico por natureza, mas feito para se aumentar a velocidade de sites dinâmicos diminuindo a carga no banco de dados&#8221;.<br />
O memcached funciona como um grande dicionário, que armazena tuplas do tipo [chave, valor]. Para armazenar um objeto qualquer, basta conectar no memcached e passar uma chave para acessá-lo e o objeto (e opcionalmente outros parâmetros, como tempo de armazenamento). Para buscar o objeto, basta conectar ao memcached e pedir a ele o objeto que possui a chave previamente criada.<br />
Digamos que uma página web precise fazer algumas consultas pesadas em um banco de dados. A idéia é justamente pegar o resultado da consulta e jogar pra dentro do memcached. Na próxima vez que a consulta precisar ser feita, o programa irá primeiro checar se o resultado já está disponível no memcached. Se estiver, ótimo, economizamos uma query pesada. Se não estiver, o programa faz a consulta e guarda o resultado no memcached. Simples assim!</p>
<h2>Exemplo em PHP</h2>
<p>O memcached pode ser acessado de muitas linguagens de alto nível, como C/C++, Java, Python, PHP, e até .NET. Abaixo, um exemplo em PHP.<br />
Antes do memcache, uma página poderia ter uma consulta do seguinte tipo:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">// A query SQL está abreviada, apenas como exemplo</span>
<span style="color: #666666; font-style: italic;">// Digamos que essa consulte demore cerca de 1 segundo</span>
<span style="color: #666666; font-style: italic;">// para ser completada</span>
<span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT * FROM tabela INNER JOIN ......&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$res</span> <span style="color: #339933;">=</span> <span style="color: #990000;">pg_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$arr</span> <span style="color: #339933;">=</span> <span style="color: #990000;">pg_fetch_all</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$res</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// array com todos os resultados</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Com esse código, a cada acesso na página, teremos uma consulta de 1 segundo feita ao banco de dados. Muitas vezes, a consulta será exatamente a mesma. Modificando a consulta para uso do memcached, teríamos algo assim:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">// Conecta ao memcached</span>
<span style="color: #000088;">$mc</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Memcache<span style="color: #339933;">;</span>
<span style="color: #000088;">$mc</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addServer</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ip.do.servidor'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT * FROM tabela INNER JOIN ......&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$cache</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$mc</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Usamos o md5() da query como chave</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$cache</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Resultado não está no cache</span>
    <span style="color: #000088;">$res</span> <span style="color: #339933;">=</span> <span style="color: #990000;">pg_query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$arr</span> <span style="color: #339933;">=</span> <span style="color: #990000;">pg_fetch_all</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$res</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$mc</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$arr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$arr</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$cache</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Pelo exemplo acima, temos algumas modificações. Primeiramente conectamos ao memcached. A chamada a addServer() pode ser feita múltiplas vezes, caso existam vários memcached rodando em máquinas separadas. Pode ser dado um &#8220;peso&#8221; pra cada servidor também, de acordo com a memória disponível em cada um.<br />
Logo em seguida, é feita a verificação no memcached se o resultado da consulta já está lá. Como chave, usei o hash md5 da consulta, pra gerar uma identificação única. O método get() pode retornar false, caso a chave não esteja no memcached, ou retornar o objeto que foi guardado.<br />
A checagem é simples. Se o get() retornou false, então o sistema faz a consulta como já fazia antes, e no fim guarda o resultado no memcached, pra agilizar as próximas consultas. E caso não tenha retornado false, temos já o resultado da consulta diretamente. Ao fim do bloco <i>if</i>, teremos, de uma forma ou de outra, o resultado da consulta em $arr.<br />
A diferença é que rodando a consulta no banco, o tempo será de cerca de 1 segundo (tempo que estimamos para a execução da consulta), e pegando o resultado direto do memcached, a consulta demorará algo da ordem de milissegundos para ser completada.</p>
<h2>Problemas</h2>
<p>Um dos problemas clássicos em qualquer abordagem que use cache é como saber se as informações em cache ainda estão atuais. Com o memcached, isso não é diferente. Existem algumas formas de se lidar com o problema.<br />
A primeira delas, mais simples, e que pode ser usada livremente caso não seja de suma importância que os dados estejam atuais, é mexer no tempo em que a informação ficará no cache. O tempo pode ser especificado na chamada ao método set(), da seguinte forma:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$mc</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$arr</span><span style="color: #339933;">,</span> MEMCACHE_COMPRESSED<span style="color: #339933;">,</span> <span style="color: #cc66cc;">60</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Temos neste exemplo todos os parâmetros para a chamada de set(): a chave, o objeto a ser guardado, uma flag (pode ser usado MEMCACHE_COMPRESSED, que indica que o objeto será comprimido para ocupar menos espaço, ou 0 pra indicar que deve ser guardado sem compressão), e por último o tempo de vida do objeto, no caso, 60 segundos.<br />
Ou seja, caso não haja problema das informações permanecerem desatualizadas por 60 segundos no máximo, essa abordagem pode ser usada.<br />
Caso a informação tenha que estar sempre atualizada, a forma de tratamento terá que ser outra. O memcached possui método para apagar o objeto associado a uma chave. Tendo a chave, basta usar:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$mc</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">delete</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'chave'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>e a entrada que existia no memcached para aquela chave será invalidada.<br />
A idéia, nesse segundo caso, é justamente localizar no código todos os pontos que modificam o banco de dados de forma que possa alterar o resultado da consulta feita, e adicionar código para invalidar o cache nesses pontos. Assim, quando for feita a consulta no memcached, caso alguma informação tenha sido modificada, a entrada correspondente no memcached já terá sido apagada, e a chamada a get() retornará false naturalmente.<br />
É claro que essa segunda abordagem dá muito mais trabalho, por isso a sugestão de se usar a primeira delas nos casos em que pode ser usada. Lembre-se que em um site com 100 acessos por segundo, um tempo de vida de 60 segundos evitará 5999 consultas ao banco (a primeira será feita e guardada).</p>
<h2>Mais informações</h2>
<p>O site do projeto tem <a href="http://code.google.com/p/memcached/wiki/Start">um Wiki</a> que responde a maior parte das dúvidas que se pode ter, em relação a instalação e ao uso.<br />
No caso do PHP, as funções são bem documentadas na <a href="http://br.php.net/manual/en/book.memcache.php">parte do manual sobre memcache</a>.<br />
Eu uso em produção o memcached, com 2 servidores, um com 768mb de memória disponíveis para o memcached e outro com 256mb. Dei pesos 3 e 1 respectivamente, para que um objeto tenha 3 vezes mais chance de cair no primeiro servidor. A configuração está bastante satisfatória, e o banco de dados agradece.</p>
<h3  class="related_post_title">Artigos relacionados</h3><ul class="related_post"><li><a href="http://www.ataraxia.com.br/posts/evitando-sql-injection-em-php" title="Evitando SQL injection em PHP">Evitando SQL injection em PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-imagens-inline" title="Otimização: imagens inline">Otimização: imagens inline</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-3-cache" title="Otimização de sites, parte 3 &#8211; Cache">Otimização de sites, parte 3 &#8211; Cache</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-2-compressao" title="Otimização de sites, parte 2 &#8211; Compressão">Otimização de sites, parte 2 &#8211; Compressão</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-em-php-parte-1-minify" title="Otimização em PHP, parte 1: Minify">Otimização em PHP, parte 1: Minify</a></li><li><a href="http://www.ataraxia.com.br/posts/problemas-com-acentuacao" title="Problemas com acentuação?">Problemas com acentuação?</a></li><li><a href="http://www.ataraxia.com.br/posts/o-limite-de-4-ou-3-gb-de-memoria" title="O limite de 4 (ou 3?) Gb de memória">O limite de 4 (ou 3?) Gb de memória</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.ataraxia.com.br/posts/otimizacao-de-sites-com-memcached/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Otimização: imagens inline</title>
		<link>http://www.ataraxia.com.br/posts/otimizacao-imagens-inline</link>
		<comments>http://www.ataraxia.com.br/posts/otimizacao-imagens-inline#comments</comments>
		<pubDate>Fri, 17 Apr 2009 14:48:33 +0000</pubDate>
		<dc:creator>Bruno Lustosa</dc:creator>
				<category><![CDATA[dicas]]></category>
		<category><![CDATA[programação]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[otimização]]></category>

		<guid isPermaLink="false">http://www.ataraxia.com.br/?p=216</guid>
		<description><![CDATA[Sempre que queremos colocar uma imagem em uma página, podemos usar a tag img: &#60;img src=&#34;imagem.png&#34; /&#62; ou então, podemos carregá-la como imagem de fundo de um elemento qualquer usando CSS: .classe &#123; background-image:url&#40;imagem.png&#41;; &#125; Um dos problemas em páginas que possuem muitas imagens é que cada imagem requer a abertura de uma nova conexão [...]]]></description>
			<content:encoded><![CDATA[<p>Sempre que queremos colocar uma imagem em uma página, podemos usar a tag <b>img</b>:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">img</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;imagem.png&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p>ou então, podemos carregá-la como imagem de fundo de um elemento qualquer usando <acronym title="Cascating Style Sheet">CSS</acronym>:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #6666ff;">.classe</span> <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">background-image</span><span style="color: #00AA00;">:</span><span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000; font-style: italic;">imagem.png</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>Um dos problemas em páginas que possuem muitas imagens é que cada imagem requer a abertura de uma nova conexão HTTP, e com a limitação de 2 conexões por host (é uma restrição dos navegadores que seguem a especificação HTTP), o tempo de carga da página pode acabar crescendo bastante.</p>
<h2>A lógica</h2>
<p>Uma solução para este problema é ao invés de carregar as imagens externas, colocá-las diretamente dentro da página, seguindo a mesma lógica que já usamos com CSS. Por exemplo, podemos especificar uma folha de estilo externa:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;arquivo.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p>ou então podemos colocar os estilos inline:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">style</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span>&gt;</span>
.classe1 { font-color:#f00; }
#id2 { width:200px; }
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">style</span>&gt;</span></pre></div></div>

<h2>Codificando a imagem</h2>
<p>Até aí, tudo bem, afinal CSS é texto, e texto entra bem dentro de uma página. Mas como colocar uma imagem dentro de uma página, uma vez que a imagem é binária?<br />
Simples! Primeiro, codificamos a imagem de binário para ASCII usando a codificação <b>base64</b>. Existem várias formas de se fazer isso, e boa parte das linguagens de programação disponibiliza funções para fazer esta codificação. Por exemplo, em PHP, podemos fazer:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">print</span> base64encode<span style="color: #009900;">&#40;</span><span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;arquivo.png&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>A saída disso é algo mais ou menos assim:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">iVBORw0KGgoAAAANSUhEUgAAAxYAAAAKCAAAAAAMKZcGAAAACXZwQWcAAAMWAAAACgALWq6
YAAAAOklEQVRYw<span style="color: #339933;">+</span>3TsQ0AIAwEMZT9F4Uh8vTUFCDZM9zV6nyt08kMXOypBnCwBdgCbAG2AF
uALcAWYAt4xQZXmxLmG7UZ3wAAAABJRU5ErkJggg<span style="color: #339933;">==</span></pre></div></div>

<p>Pronto, já temos a representação codificada da imagem.<br />
Para que a saída coubesse na tela, quebrei a saída em 3 linhas. A saída real é toda em uma só linha, mas como veremos adiante, tanto faz, pois podemos usar quebras de linha.</p>
<h2>URLs do tipo &#8220;data&#8221;</h2>
<p>Antes de colocarmos a imagem dentro da página, precisamos ver como funcionam as URLs do tipo &#8220;data&#8221;. A URL segue o seguinte formato:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;">data:[<span style="color: #009900;">&lt;tipo MIME&gt;</span>][;charset=&quot;<span style="color: #009900;">&lt;charset&gt;</span>&quot;][;base64],<span style="color: #009900;">&lt;dados&gt;</span></pre></div></div>

<p>onde:</p>
<ul>
<li><em>tipo MIME</em> é o tipo do arquivo que vamos colocar, no nosso caso, <b>image/png</b>;</li>
<li><em>charset</em> é a codificação utilizada, para o caso de arquivos texto (não usaremos no nosso exemplo).</li>
<li><em>base64</em> é a codificação utilizada. Se for omitida, o navegador entenderá que estamos usando US-ASCII, e no caso de imagens, não vai dar certo;</li>
<li>e por último, <em>dados</em> contém a string com o arquivo codificado (aquela sequencia grande de caracteres ali de cima). A string pode ser quebrada com espaços ou quebras de linha.</li>
</ul>
<p></p>
<h2>Juntando tudo</h2>
<p>Pois bem, agora que temos a representação codificada da imagem e já sabemos usar URLs do tipo &#8220;data&#8221;, podemos colocá-la diretamente na página, usando a própria tag <b>img</b>:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">img</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAxYAAAAKCAAAAAAMKZc</span>
<span style="color: #009900;">GAAAACXZwQWcAAAMWAAAACgALWq6YAAAAOklEQVRYw+3TsQ0AIAwEMZT9F4Uh8vTUFCDZM9zV6n</span>
<span style="color: #009900;">yt08kMXOypBnCwBdgCbAG2AFuALcAWYAt4xQZXmxLmG7UZ3wAAAABJRU5ErkJggg==&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p>Ou então uma regra de CSS, da seguinte forma:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #6666ff;">.classe</span> <span style="color: #00AA00;">&#123;</span> <span style="color: #000000; font-weight: bold;">background-image</span><span style="color: #00AA00;">:</span><span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span>data<span style="color: #00AA00;">:</span>image/png<span style="color: #00AA00;">;</span>base64<span style="color: #00AA00;">,</span>iVBORw0KGgoAAAANSUh
EUgAAAxYAAAAKCAAAAAAMKZcGAAAACXZwQWcAAAMWAAAACgALWq6YAAAAOklEQVRYw<span style="color: #00AA00;">+</span>3TsQ0
AIAwEMZT9F4Uh8vTUFCDZM9zV6nyt08kMXOypBnCwBdgCbAG2AFuALcAWYAt4xQZXmxLmG7U
Z3wAAAABJRU5ErkJggg<span style="color: #00AA00;">==</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span> <span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>É claro que usar esta técnica, como quase tudo na vida, tem várias vantagens e desvantagens.</p>
<h2>As vantagens</h2>
<p>Temos várias vantagens em usar um esquema deste tipo:</p>
<ul>
<li>Suporte na grande maioria dos navegadores modernos: Firefox, Opera, Safari, Konqueror e Chrome;</li>
<li>Antes de mais nada, estamos diminuindo o número de requisições HTTP, e consequentemente, evitamos o tráfego associado à requisição (cabeçalhos HTTP);</li>
<li>Como a imagem está inline, conseguimos &#8220;fugir&#8221; do limite de 2 conexões por host, já que estamos evitando a abertura de novas conexões;</li>
<li>Para imagens pequenas, temos um ganho real em bytes transferidos, pois embora a imagem codificada em base64 fique maior, estamos evitando de enviar os cabeçalhos HTTP (que somam em média 200 bytes).</li>
<li>Conexões seguras (que usam https) só mostram o &#8220;cadeado&#8221; fechado se todos os elementos externos forem carregados através de https também. E o <em>overhead</em> associado a uma conexão https é bem maior que o de uma conexão http normal. Com a imagem inline, ganhamos mais um pouco.</li>
</ul>
<p></p>
<h2>As desvantagens</h2>
<p>Temos várias desvantagens, algumas contornáveis:</p>
<ul>
<li>Internet Explorer até a versão 7 não tem suporte. Só a partir do 8. A forma de se usar para os dois navegadores é usando arquivos CSS separados para cada navegador (ou um pré-processador de CSS que detecte o navegador e dê a saída com o que for suportado);</li>
<li>Imagem inline em uma página (usando tag <b>img</b>) não são cacheadas pelo navegador. Se usada dentro do CSS, aí sim teremos o cache em ação, pois o navegador irá cachear o CSS;</li>
<li>Uma imagem codificada em base64 tem seu tamanho aumentado em 33%. Para imagens grandes, é uma perda considerável, mas para imagens pequenas (da ordem de 500 bytes), temos um ganho, pois mesmo com o aumento da imagem, estamos evitando o envio dos cabeçalhos, e podemos sair ganhando na soma;</li>
<li>Dificuldade de manutenção: se uma imagem é alterada, ela precisa ser recodificada. Existem formas de se automatizar isso.</li>
</ul>
<p></p>
<h2>Um exemplo</h2>
<p>A imagem que aparece aqui embaixo está inline, e foi colocada usando uma tag <b>img</b> (a qualidade está baixa pra não ficar muito grande):</p>
<p><img src="data:image/png;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAFA3PEY8MlBGQUZaVVBfeMiCeG5uePWvuZHI////////////////////////////////////////////////////2wBDAVVaWnhpeOuCguv/////////////////////////////////////////////////////////////////////////wAARCADwAUADASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAECAwT/xAAxEAACAgEDBAEEAgEEAwADAAABAgARIQMSMSJBUWETMnGBkaHwwSMzQrFS0eFigvH/xAAWAQEBAQAAAAAAAAAAAAAAAAAAAQL/xAAdEQEBAQADAQEBAQAAAAAAAAAAEQEhMUFhAlFx/9oADAMBAAIRAxEAPwDHev8A4j9RbwPUkmhxmRN7rV1puvvK27gRMZemxuozf6l/pVQoxULmxKsOpbPmAOmvIz7jcUtNcWR9sxM1Gh2lq25pmykE3x2l8Auob6uJq4sBhkV2mAGfM3J+OjeaqMMZKttXM3ZlApvx5EzGsSabj1K1VJO4cHv4hapSu0lATQ7yRquHonHePRUqpY4HuNH0y4oEHtZxBRqIzHi/xLcKQAzUarMzdnGpg1niW6bm5APgmFoYqtLRMZB3gAWv2g7KpClb7Xcqn+Uc1f4gqNg3HjAi2bh9MtQoZipsgcQvfpm6XMVagoq4Ni4DSqzUskKFwG9yttapN2a4ilZBQynFVGy0AR+5QO4MCAoHcQGNOtMkxSpcBKJGfEGQMQwIA94jP+2DqDP8xH/VQbceoSlqi1AGRXPmNCfjtsgeYC9PT93JR2clWG4QUhq9VbQB6jbSB7gAeYbFDWWH+Yteya7VcChQUgG+9zmYcY5mmjYbFynCEWSVvmO0tTpDJ7YlM4X6gD9xGpWqX9+Zi2STHh4v5QccfiGopK2JiJshG3qyCIzambe2TA1EBNW0zZK5BkBGPMm4bgUG5Q5wazKVdq1+8SHNfcTXWL0l+ZPaWQSPckYGZjcZKUv1DzF9poiUNx/EZgDjMzM1PUD/ABM6oUZf0aSmjjmb3jIBHOZiqljQE2f6SBmME/Iq4VR95RHyICpsjNeZhU20VtT9xmMpUrpOW+kj7zR3OnQQ58zJtRiecTVafT6sEdxFKWm/yWrm7HMp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" /></p>
<p>Clicando o botão direito na imagem e escolhendo &#8220;Exibir imagem&#8221; (no Firefox ou em outro navegador que dê suporte), dá pra se ver na barra de endereços a URL usada pra criar a imagem.<br />
E claro, se você não está vendo imagem nenhuma, provavelmente está usando o Internet Explorer. E já passou da hora de passar a usar um <a href="http://www.getfirefox.com/">navegador decente, que suporta os padrões web</a>, não é?</p>
<h3  class="related_post_title">Artigos relacionados</h3><ul class="related_post"><li><a href="http://www.ataraxia.com.br/posts/evitando-conteudo-duplicado" title="Evitando conteúdo duplicado">Evitando conteúdo duplicado</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-de-sites-com-memcached" title="Otimização de sites com memcached">Otimização de sites com memcached</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-3-cache" title="Otimização de sites, parte 3 &#8211; Cache">Otimização de sites, parte 3 &#8211; Cache</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-2-compressao" title="Otimização de sites, parte 2 &#8211; Compressão">Otimização de sites, parte 2 &#8211; Compressão</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-em-php-parte-1-minify" title="Otimização em PHP, parte 1: Minify">Otimização em PHP, parte 1: Minify</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.ataraxia.com.br/posts/otimizacao-imagens-inline/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Otimização de sites, parte 3 &#8211; Cache</title>
		<link>http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-3-cache</link>
		<comments>http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-3-cache#comments</comments>
		<pubDate>Wed, 15 Apr 2009 12:42:12 +0000</pubDate>
		<dc:creator>Bruno Lustosa</dc:creator>
				<category><![CDATA[dicas]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[otimização]]></category>

		<guid isPermaLink="false">http://www.ataraxia.com.br/?p=259</guid>
		<description><![CDATA[Nos outros dois artigos sobre otimização, já vimos como diminuir o número de requisições usando o Minify e também como diminuir o tamanho dos arquivos transferidos usando compressão. Neste artigo, apresentarei mais uma forma de se conseguir diminuir mais ainda o tempo de carga de uma página, usando a técnica de caching. Como o cache [...]]]></description>
			<content:encoded><![CDATA[<p>Nos outros dois artigos sobre otimização, já vimos <a href="http://www.ataraxia.com.br/posts/otimizacao-em-php-parte-1-minify">como diminuir o número de requisições usando o Minify</a> e também como <a href="http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-2-compressao">diminuir o tamanho dos arquivos transferidos usando compressão</a>.<br />
Neste artigo, apresentarei mais uma forma de se conseguir diminuir mais ainda o tempo de carga de uma página, usando a técnica de <em>caching</em>.</p>
<h2>Como o cache pode ajudar?</h2>
<p>Nos outros artigos, vimos como diminuir o número de requisições (agrupando vários arquivos em um só) e também como diminuir o tamanho do que é transferido.<br />
Mas&#8230; e se não precisarmos fazer todas essas requisições? A grande maioria das páginas de um site tem arquivos em comum, e que não mudam. Imagens estáticas, folhas de estilo CSS e scripts em JavaScript. E após a primeira carga, o navegador já vai ter esses arquivos localmente.<br />
Só nos resta dizer pra ele quando e o que ele pode usar nas requisições seguintes.</p>
<h2>Quais as formas de se usar o cache?</h2>
<p>Uma vez que o navegador tenha, digamos, uma imagem estática em cache, existem duas formas dele proceder pra saber se o arquivo é atual ou não.<br />
A primeira é fazer uma requisição indicando a data em que o arquivo foi buscado. Essa requisição é feita enviando um cabeçalho &#8220;If-Modified-Since&#8221;, com a data do arquivo local. Caso o arquivo não tenha sido modificado, o servidor responde com o código 304 (Not Modified) ao invés de devolver o arquivo novamente.<br />
A segunda forma é somente pedir o arquivo caso ele já tenha expirado.<br />
Logicamente a segunda forma é bem mais econômica, pois evita a abertura da conexão.<br />
Porém, temos um problema: como saber se um arquivo já expirou?</p>
<h2>O cabeçalho &#8220;Expires&#8221;</h2>
<p>Qualquer arquivo solicitado em uma conexão HTTP pode ter associado um cabeçalho <em>Expires</em>, que indica explicitamente a &#8220;data de vencimento&#8221; daquele arquivo. Ou seja, até a data especificada, o arquivo é válido e não precisa ser checado novamente. Após isso, o navegador deve considerar o arquivo como expirado, e solicitar novamente.<br />
Então, para arquivos estáticos, podemos colocar uma regra dizendo que a data de vencimento dele é em um futuro distante. Isso pode ser feito, em um servidor Apache, com uma regra semelhante a esta:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">ExpiresActive</span> <span style="color: #0000ff;">On</span>
<span style="color: #00007f;">ExpiresByType</span> image/gif <span style="color: #7f007f;">&quot;access plus 5 years&quot;</span>
<span style="color: #00007f;">ExpiresByType</span> image/jpeg <span style="color: #7f007f;">&quot;access plus 5 years&quot;</span>
<span style="color: #00007f;">ExpiresByType</span> image/png <span style="color: #7f007f;">&quot;access plus 5 years&quot;</span>
<span style="color: #00007f;">ExpiresByType</span> text/css <span style="color: #7f007f;">&quot;access plus 5 years&quot;</span></pre></div></div>

<p>Neste exemplo (que utilizo aqui neste site), estou indicando explicitamente que arquivos do tipo GIF, JPEG, PNG e CSS tem validade de 5 anos da data do download. Antes disso, o navegador pode assumir que o conteúdo é atual e utilizá-lo.<br />
Deixei o JavaScript de lado porque atualmente não estou utilizando nenhum script neste site. Caso queira adicionar na lista, basta duplicar uma das linhas, usando o tipo <em>text/javascript</em>.<br />
Após o primeiro acesso, todas as imagens e folhas de estilo serão cacheadas, e o navegador não irá solicitá-las novamente. Isso dá um bom ganho de desempenho, pois o número de requisições necessárias para carregar as páginas subsequentes (e o correspondente tamanho em bytes) cai consideravelmente.</p>
<h2>O resultado</h2>
<p>Tomando como exemplo a <a href="http://www.ataraxia.com.br/">página inicial deste site</a>, e testando com um navegador com o cache completamente limpo, temos, para o primeiro acesso 21 conexões, sendo 1 para a página propriamente dita, 3 arquivos CSS externos, e 17 imagens externas.<br />
Em um segundo acesso à mesma página (cliquei no logotipo lá em cima à esquerda), apenas uma única conexão foi aberta, para baixar somente a página em si. Todas as imagens e folhas de estilo já estavam no cache do navegador, e ele &#8220;sabe&#8221; que elas só vão expirar daqui a 5 anos. Logo, não tem porque verificar se foram alteradas.</p>
<h2>Possíveis problemas</h2>
<p>Um dos problemas neste tipo de configuração é o que fazer caso se precise fazer uma alteração em uma imagem ou em um arquivo CSS.<br />
Nesses casos, como o navegador não está nem checando, o melhor a fazer é alterar o nome do arquivo, por exemplo, colocando um número contendo a versão ou a data de modificação. Com isso, o navegador irá interpretar o arquivo como algo novo, que ele ainda não possui em cache, e que precisa ser baixado.<br />
Porém, o ganho que se consegue com o uso dessa técnica faz, na minha opinião, valer a pena o esforço. Existem algumas formas de se automatizar o processo de alteração do nome do arquivo, que deixarei para discutir em um outro artigo.</p>
<h3  class="related_post_title">Artigos relacionados</h3><ul class="related_post"><li><a href="http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-2-compressao" title="Otimização de sites, parte 2 &#8211; Compressão">Otimização de sites, parte 2 &#8211; Compressão</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-em-php-parte-1-minify" title="Otimização em PHP, parte 1: Minify">Otimização em PHP, parte 1: Minify</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-de-sites-com-memcached" title="Otimização de sites com memcached">Otimização de sites com memcached</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-imagens-inline" title="Otimização: imagens inline">Otimização: imagens inline</a></li><li><a href="http://www.ataraxia.com.br/posts/paginas-de-manutencao" title="Páginas de manutenção">Páginas de manutenção</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-3-cache/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Otimização de sites, parte 2 &#8211; Compressão</title>
		<link>http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-2-compressao</link>
		<comments>http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-2-compressao#comments</comments>
		<pubDate>Tue, 10 Mar 2009 03:21:36 +0000</pubDate>
		<dc:creator>Bruno Lustosa</dc:creator>
				<category><![CDATA[dicas]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[otimização]]></category>

		<guid isPermaLink="false">http://www.ataraxia.com.br/?p=201</guid>
		<description><![CDATA[Como vimos no primeiro artigo da série sobre otimização em PHP, minimizar o número de conexões feitas pelo navegador é algo fundamental, pois muitas vezes perdemos mais tempo para estabelecer as conexões HTTP do que baixando o conteúdo propriamente dito. Porém, tão importante quanto minimizar o número de conexões, é ter certeza de que a [...]]]></description>
			<content:encoded><![CDATA[<p>Como vimos no <a href="http://www.ataraxia.com.br/posts/otimizacao-em-php-parte-1-minify">primeiro artigo da série sobre otimização em PHP</a>, minimizar o número de conexões feitas pelo navegador é algo fundamental, pois muitas vezes perdemos mais tempo para estabelecer as conexões <acronym title="HyperText Transfer Protocol">HTTP</acronym> do que baixando o conteúdo propriamente dito.</p>
<p>Porém, tão importante quanto minimizar o número de conexões, é ter certeza de que a quantidade de dados transferidos seja sempre a menor possível. Como vimos antes, o Minify já ajuda nesse sentido, pois retira dos scripts e das folhas de estilo caracteres desnecessários como espaços em branco e quebras de linha.</p>
<p>Este artigo não é específico de PHP, pois lida uma camada abaixo, direto no protocolo HTTP. As soluções apresentadas aqui podem ser implementadas diretamente na linguagem, mas ficam bem melhores se implementadas no servidor (Apache, no caso), como demonstrado neste artigo.</p>
<p>Começando com o HTTP 1.1, os navegadores podem especificar formas de codificação aceitáveis para o conteúdo, através do cabeçalho <em>Accept-Encoding</em>. Por exemplo, utilizando:</p>

<div class="wp_syntax"><div class="code"><pre class="http" style="font-family:monospace;">Accept-Encoding: gzip, deflate</pre></div></div>

<p>o navegador indica para o servidor web que pode receber o conteúdo solicitado de forma comprimida, utilizando um destes dois métodos (gzip ou deflate). Caso o servidor possa comprimir utilizando uma das formas solicitadas, irá retornar um cabeçalho <em>Content-Encoding</em>, informando a codificação usada, como por exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="http" style="font-family:monospace;">Content-Encoding: gzip</pre></div></div>

<p>A codificação mais popular hoje em dia é o gzip, que é uma especificação aberta e bem documentada pela <a href="http://www.ietf.org/rfc/rfc1952.txt">RFC 1952</a>. A outra codificação (deflate) também pode ser usada, mas é menos popular e menos eficiente que o gzip.</p>
<p>A codificação gzip consegue comprimir conteúdo texto (HTML, CSS, JavaScript, e outros) em aproximadamente 70%. Levando-se em consideração que mais de 90% dos navegadores atualmente em uso suportam esta compressão, é altamente recomendável configurar o servidor web para comprimir arquivos texto.</p>
<p>Para o <a href="http://apache.httpd.org/">Apache</a>, dependerá da versão utilizada. O Apache 1.3 utiliza o <a href="http://sourceforge.net/projects/mod-gzip/">mod_gzip</a>, enquanto que o Apache 2.x usa o <a href="http://httpd.apache.org/docs/2.0/mod/mod_deflate.html">mod_deflate</a>. Como o Apache 1.3 já não é muito utilizado, vou mostrar os exemplos  para o mod_deflate.</p>
<p>Devemos levar em conta que somente arquivos texto devem ser comprimidos. Arquivos binários, como imagens, áudio e vídeo em geral já estão em um formato comprimido, e colocar mais compressão em cima, além de não diminuir o tamanho do arquivo (pelo contrário, as vezes até aumenta!), causa também desperdício de CPU para o servidor.</p>
<p>A configuração do mod_deflate em geral é feita especificando quais tipos de arquivo serão comprimidos. Em geral, arquivos texto devem ser comprimidos. Podemos, por exemplo, especificar que alguns tipos devem ser comprimidos utilizando diretivas de Apache como:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">SetOutputFilter</span> DEFLATE
<span style="color: #00007f;">AddOutputFilterByType</span> DEFLATE text/html text/plain text/xml text/css text/javascript text/x-json</pre></div></div>

<p>A primeira linha liga o mecanismo de compressão do mod_deflate, e a segunda especifica alguns tipos que devem ser comprimidos. No caso, estou informando ao servidor que arquivos tipo <acronym title="HyperText Markup Language">HTML</acronym>, texto puro, <acronym title="eXtensible Markup Language">XML</acronym>, <acronym title="Cascading Style Sheet">CSS</acronym>, JavaScript e <acronym title="JavaScript Object Notation">JSON</acronym> devem ser comprimidos. Alguns navegadores mais antigos podem ter problemas com a compressão gzip, mas felizmente isto é coisa do passado. De qualquer forma, a página com a documentação do mod_deflate mostra como desligar a compressão de acordo com o navegador usado.</p>
<p>Um bom site para se testar se o servidor está configurado corretamente para servir conteúdo comprimido é o <a href="http://whatsmyip.org/mod_gzip_test/">mod_gzip Test</a>. Basta colocar a <acronym title="Uniform Resource Locator">URL</acronym> do site e clicar em &#8220;Test&#8221; para saber se o servidor está preparado para servir conteúdo comprimido.</p>
<h3  class="related_post_title">Artigos relacionados</h3><ul class="related_post"><li><a href="http://www.ataraxia.com.br/posts/otimizacao-em-php-parte-1-minify" title="Otimização em PHP, parte 1: Minify">Otimização em PHP, parte 1: Minify</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-3-cache" title="Otimização de sites, parte 3 &#8211; Cache">Otimização de sites, parte 3 &#8211; Cache</a></li><li><a href="http://www.ataraxia.com.br/posts/envio-de-emails-em-massa" title="Envio de emails em massa">Envio de emails em massa</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-de-sites-com-memcached" title="Otimização de sites com memcached">Otimização de sites com memcached</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-imagens-inline" title="Otimização: imagens inline">Otimização: imagens inline</a></li><li><a href="http://www.ataraxia.com.br/posts/acessando-sites-fora-do-ar" title="Acessando sites fora do ar">Acessando sites fora do ar</a></li><li><a href="http://www.ataraxia.com.br/posts/paginas-de-manutencao" title="Páginas de manutenção">Páginas de manutenção</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-2-compressao/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Otimização em PHP, parte 1: Minify</title>
		<link>http://www.ataraxia.com.br/posts/otimizacao-em-php-parte-1-minify</link>
		<comments>http://www.ataraxia.com.br/posts/otimizacao-em-php-parte-1-minify#comments</comments>
		<pubDate>Thu, 26 Feb 2009 04:13:37 +0000</pubDate>
		<dc:creator>Bruno Lustosa</dc:creator>
				<category><![CDATA[dicas]]></category>
		<category><![CDATA[programação]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[otimização]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.ataraxia.com.br/?p=196</guid>
		<description><![CDATA[Este é o primeiro artigo de uma série sobre otimização de páginas. Existem muitas técnicas que podemos utilizar pra melhorar o desempenho e o tempo de carregamento de uma página. Existem alguns fatores que influenciam no tempo de carregamento de uma página: Tamanho total dos dados Tempo de geração da página Número de conexões HTTP [...]]]></description>
			<content:encoded><![CDATA[<p>Este é o primeiro artigo de uma série sobre otimização de páginas. Existem muitas técnicas que podemos utilizar pra melhorar o desempenho e o tempo de carregamento de uma página.</p>
<p>Existem alguns fatores que influenciam no tempo de carregamento de uma página:</p>
<ul>
<li>Tamanho total dos dados</li>
<li>Tempo de geração da página</li>
<li>Número de conexões <acronym title="HyperText Transfer Protocol">HTTP</acronym> necessárias</li>
</ul>
<p>O tamanho total dos dados é de extrema importância, pois quanto mais dados pra se transferir (páginas, imagens, folhas de estilo, scripts externos, etc), maior o tempo de carregamento de uma página. O tempo de geração também é importante, e este tempo depende de uma programação eficiente e de um banco de dados rápido.</p>
<p>Porém, o número de conexões necessárias é frequentemente esquecido, e é um fator de extrema importância para que uma página seja carregada rapidamente.</p>
<p>Para entendermos o porque, precisamos saber o que o navegador faz quando pedimos para ele abrir uma página.</p>
<p>Primeiramente, é realizada uma consulta ao servidor <acronym title="Domain Name System">DNS</acronym> para se determinar o endereço do servidor que estamos tentando acessar. Esta consulta leva algum tempo, mas normalmente é cacheada pelo navegador uma vez feita. Num segundo passo, temos a primeira conexão, que baixa a página que foi pedida.</p>
<p>Após a busca da página, o navegador analisa sua estrutura, e busca elementos externos necessários, como imagens, folhas de estilo (<acronym title="Cascading Style Sheet">CSS</acronym>), scripts, arquivos de Flash, etc etc.</p>
<p>Cada elemento externo a ser baixado exige a abertura de mais uma conexão HTTP (nem sempre&#8230; existe pipelining e outras coisas que melhoram isso, mas pra simplificar, vou ignorar por enquanto). Cada conexão, para ser estabelecida, leva um tempo antes da transferência de dados ser iniciada. Este overhead gera um atraso, visto que muitas vezes, dependendo do tamanho do arquivo, o tempo para se estabelecer a conexão chega a ser maior que o tempo para se baixar o arquivo.</p>
<p>Some-se a isso uma regra que diz que navegadores devem abrir no máximo 2 conexões simultâneas por host. Ou seja, se a página possui 30 elementos externos a serem baixados, as conexões serão estabelecidas duas a duas até que os 30 sejam completados. Algo que se pode fazer para melhorar isto é dividir os elementos externos em alguns hosts diferentes, já que a regra manda 2 conexões <strong>por host</strong>, mas isto fica para mais adiante.</p>
<p>Muitas vezes, uma página possui vários arquivos CSS e vários scripts em JavaScript. Ao invés de utilizar, digamos, 5 tags para se carregar 5 arquivos CSS diferentes, e mais 10 tags para carregarmos 10 scripts externos, não seria muito melhor se pudéssemos abrir apenas duas conexões, e baixar todo o CSS em uma, e todo o JavaScript em outra? E melhor, que ao fazer isto eles já viessem &#8220;condensados&#8221;, de forma a diminuir seu tamanho?</p>
<p>Pois bem, a idéia do <a href="http://code.google.com/p/minify/">Minify</a> é justamente fazer isto. O Minify é um script em PHP que recebe uma lista de arquivos como parâmetro (CSS ou JavaScript) e &#8220;junta&#8221; todos eles em um único download (ele faz mais, mas para mais detalhes, veja direto na página do Minify).</p>
<p>Para fazer a instalação, tudo muito simples. Basta descompactar o arquivo na raiz do site, e fazer algumas modificações nas tags. Ao invés de termos:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/js/script1.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/js/script2.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/js/script3.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/js/script4.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/js/script5.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></pre></div></div>

<p>passamos a ter somente:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/min/?f=/js/script1.js,/js/script2.js,/js/script3.js,/js/script4.js,/js/script5.js&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></pre></div></div>

<p>Ou seja, chamamos somente o &#8220;/min/&#8221;, e passamos como parâmetro (chamado <b>f</b>) uma lista com os scripts, separados por vírgulas, e o Minify se encarrega do resto. Com o CSS, a mesma coisa. Ao invés de termos:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/css/style1.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/css/style2.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/css/style3.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/css/style4.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/css/style5.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p>teremos somente:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">link</span> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/min/?f=/css/style1.css,/css/style2.css,/css/style3.css,/css/style4.css,/css/style5.css&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></pre></div></div>

<p>Apenas usando o Minify, já podemos conseguir baixar o número de conexões HTTP necessárias para se carregar a página inteira, e com isso, diminuir o tempo total.</p>
<p>Um site interessante, que fornece um mapa com todos os elementos do site, assim como o tempo de carregamento de cada um é o <a href="http://tools.pingdom.com/">Full Page Test do Pingdom</a>. O tempo de cada elemento é dividido em 3: tempo para se começar, tempo para se estabelecer a conexão e a transferência em si. Olhando bem, dá pra perceber que o tamanho das páginas (parte azul da barra) tem uma influência menor do que o número de conexões.</p>
<p>Existem outras técnicas, que podem ser usadas em conjunto com o Minify para melhorar ainda mais, mas ficarão para os próximos artigos da série.</p>
<h3  class="related_post_title">Artigos relacionados</h3><ul class="related_post"><li><a href="http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-2-compressao" title="Otimização de sites, parte 2 &#8211; Compressão">Otimização de sites, parte 2 &#8211; Compressão</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-de-sites-parte-3-cache" title="Otimização de sites, parte 3 &#8211; Cache">Otimização de sites, parte 3 &#8211; Cache</a></li><li><a href="http://www.ataraxia.com.br/posts/agendando-eventos-no-wordpress" title="Agendando eventos no WordPress">Agendando eventos no WordPress</a></li><li><a href="http://www.ataraxia.com.br/posts/removendo-o-generator-do-wordpress" title="Removendo o &#8220;generator&#8221; do Wordpress">Removendo o &#8220;generator&#8221; do Wordpress</a></li><li><a href="http://www.ataraxia.com.br/posts/envio-de-emails-em-massa" title="Envio de emails em massa">Envio de emails em massa</a></li><li><a href="http://www.ataraxia.com.br/posts/escrevendo-plugins-para-o-wordpress" title="Escrevendo plugins para o Wordpress">Escrevendo plugins para o Wordpress</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-de-sites-com-memcached" title="Otimização de sites com memcached">Otimização de sites com memcached</a></li><li><a href="http://www.ataraxia.com.br/posts/evitando-sql-injection-em-php" title="Evitando SQL injection em PHP">Evitando SQL injection em PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/otimizacao-imagens-inline" title="Otimização: imagens inline">Otimização: imagens inline</a></li><li><a href="http://www.ataraxia.com.br/posts/criando-captchas-em-php" title="Criando CAPTCHAs em PHP">Criando CAPTCHAs em PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/pegadinhas-no-php" title="Pegadinhas no PHP">Pegadinhas no PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/precedencia-no-php" title="Precedência no PHP">Precedência no PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/acessando-sites-fora-do-ar" title="Acessando sites fora do ar">Acessando sites fora do ar</a></li><li><a href="http://www.ataraxia.com.br/posts/paginas-de-manutencao" title="Páginas de manutenção">Páginas de manutenção</a></li><li><a href="http://www.ataraxia.com.br/posts/imprimindo-em-formularios-continuos-em-php" title="Imprimindo em formulários contínuos em PHP">Imprimindo em formulários contínuos em PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/xml-no-php-com-xml_serializer-parte-2-de-2" title="XML no PHP com XML_Serializer, parte 2 de 2">XML no PHP com XML_Serializer, parte 2 de 2</a></li><li><a href="http://www.ataraxia.com.br/posts/xml-no-php-com-xml_serializer-parte-1-de-2" title="XML no PHP com XML_Serializer, parte 1 de 2">XML no PHP com XML_Serializer, parte 1 de 2</a></li><li><a href="http://www.ataraxia.com.br/posts/envio-de-emails-em-php" title="Envio de emails em PHP">Envio de emails em PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/validacao-de-dados-em-php" title="Validação de dados em PHP">Validação de dados em PHP</a></li><li><a href="http://www.ataraxia.com.br/posts/seguranca-no-envio-de-emails" title="Segurança no envio de emails em PHP">Segurança no envio de emails em PHP</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.ataraxia.com.br/posts/otimizacao-em-php-parte-1-minify/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

