As aplicações web estão cada vez mais robustas – muitas delas recebem milhões de usuários por dia -, mas será que elas realmente aguentam essa quantidade de requisições mantendo a qualidade de seus serviços?
Nosso objetivo hoje é aprender a otimizar nossas aplicações front-end para que o usuário tenha a melhor experiência possível.
Configurando nosso servidor
Para configurar nossos servidores, utilizaremos exemplos no apache, mas tudo que será explicado é valido para outros servidores, como IIS e Nginx.
Gzip
O Gzip é um software para compressão e descompressão de arquivos. Ele é altamente utilizado em websites para aumentar a performance. Sites que utilizam o o Gzip podem ser até 80% mais rápidos.
Como configuramos nossos servidores para utilizar o Gzip? Muito simples, basta informarmos ao .htaccess que queremos utilizá-lo. Exemplo:
<IfModule mod_filter.c>
AddOutputFilterByType DEFLATE application/atom+xml \
application/javascript \
application/json \
application/rss+xml \
application/vnd.ms-fontobject \
application/x-font-ttf \
application/xhtml+xml \
application/xml \
font/opentype \
image/svg+xml \
image/x-icon \
text/css \
text/html \
text/plain \
text/x-component \
text/xml
</IfModule>
Configurando o cache
Muitas vezes pensamos que o browser do cliente irá fazer o cache automático de nossa aplicação, mas precisamos informá-lo de como fazer o cache da maneira correta. Para isso utilizamos os recursos do response headers.
ETags
- A Etag é um mecanismo para identificação de um componente em cache. Em outras palavras, um componente é identificado por uma string única e o browser pode verificar se ela foi modificada ou não;
- O problema das Etags é que elas são geradas para um único servidor sendo inviável validá-la em outro servidor;
- A melhor solução então é cancelar o uso da Etag, dessa forma o browser não irá verificar o componente. Isso trás uma performance significativa para o website.
# FileETag None is not enough for every server.
<IfModule mod_headers.c> Header unset ETag </IfModule>
# Since we're sending far-future expires, we don't need ETags for static content.
FileETag None
Invalide o cache
- Invalidar o cache também é uma ótima estratégia para alteração de conteúdo;
- Podemos utilizar uma estratégia de versionamento de componentes (css, js), assim o servidor saberá quando um arquivo foi alterado e precisa ser recarregado;
- Utilize helpers server-side para o versionamento dos arquivos.
Defina o tempo de cache para cada tipo de arquivo
- O famoso Expires dos servidores é uma das melhores soluções para controle de cache;
- Utilizamos diversos “tempos” diferentes para cada tipo de arquivo, por exemplo, arquivos como imagem podem ter um cache menor que um javascript.
<IfModule mod_expires.c> ExpiresActive on
# Favicon (cannot be renamed) ExpiresByType image/x-icon "access plus 1 week"
# Media: images, video, audio ExpiresByType image/gif "access plus 1 month" ExpiresByType image/png "access plus 1 month" ExpiresByType image/jpeg "access plus 1 month" ExpiresByType video/ogg "access plus 1 month" ExpiresByType audio/ogg "access plus 1 month" ExpiresByType video/mp4 "access plus 1 month" ExpiresByType video/webm "access plus 1 month"
# CSS and JavaScript ExpiresByType text/css "access plus 1 year" ExpiresByType application/javascript "access plus 1 year"
</IfModule>
Reduzindo as requisições
Reduzir a quantidade de requisições que a aplicação faz para nossos servidores é uma ótima solução para otimizarmos o carregamento da página, mas para isso precisamos entender como fazer isso.
- Um browser pode carregar até três arquivos em paralelo para cada servidor;
- Deixe os arquivos estáticos em servidores CDN com subdomínios, dessa forma o browser poderá carregar três arquivos para cada subdomínio em paralelo;
- Exemplo: um website com nove js sendo carregados no mesmo servidor, irá carregar três deles em paralelos, depois mais três e mais três. Já com o CDN com três subdomínios, ele poderá carregar os nove em paralelo.
Minificar e unificar js e css
Essa estratégia é considerada uma das melhores para obtermos uma boa performance, o problema é que a maioria dos desenvolvedores não utiliza. Vamos entender como funciona:
Ferramentas para comprimir arquivos
- YUI Compressor – Ferramenta de Yahoo que promete ser a mais segura e eficiente de todas;
- Packer – Comprime JS pela web;
- JSCompress.com – Usa JSMin ou Packer para reduzir o tamanho dos arquivos;
- CSS Compressor – Comprime arquivos CSS;
- Easy YUI compressor – Versão visual do YUI compressor.
Ferramentas para unificar arquivos
Normalmente, essas ferramentas são executadas em tempo de execução, elas comprimem e unificam os arquivos, logo em seguida armazenam os arquivos gerados em cache.
- Minify – Ferramenta em PHP que utiliza a biblioteca YUI compressor;
- Zend_Minify – API do Zend Framework para YUI compressor;
- Easy Minify – API do Easy Framework para YUI compressor;
- YUI compressor for .net. – Biblioteca para .NET;
- Ant – Biblioteca para Java.
Otimização de imagens
As imagens são os maiores responsáveis pela baixa performance de websites e aplicações. Felizmente, existem formas de contornar esse problema:
- Não coloque imagens maiores do que o necessário;
- Comprima as imagens;
- Use os formatos corretos para cada ocasião;
- Defina o tamanho e a largura da imagem no HTML;
- Use Sprites onde possível.
Css Sprite
Sprite é uma imagem que contém outras imagens dentro dela, onde nós podemos pegá-las através do css e manipulá-la de diversas formas.
- Diminui significativamente as requisições para o servidor;
- As imagens são manipuladas pelo css através da posição no arquivo.
Ferramentas para compressão de imagens e criação de sprites
- Caesium – Promete comprimir imagens em até 90%;
- Smush.it™ – Compressor de imagens da Yahoo;
- Data URI Sprites – Gerador de sprites baseado na web;
- Spritr – Gera código css para sprites;
- SmartSprites – Gerador de sprites para desktop.
Boas práticas
Organização do HTML
- Arquivos css no topo do documento – Isso irá evitar que páginas sejam carregadas sem o seu estilo, evitando problemas de “flickering” nas páginas;
- Arquivos js no final do arquivo – O carregamento de javascript é algo bloqueante, então, se nós colocarmos no inicio da página nosso cliente ficará esperando o carregamento do js, levando mais tempo para a execução;
- Deixe os arquivos de mesmo tipo próximos – Uma forma de otimizar o carregamento é entender como o interpretador do browser funciona, arquivos do mesmo tipo próximos um do outro será mais rápido do que intercalá-los;
- Crie arquivos css e js externos;
- Evite duplicação de scripts;
- Quebre os componentes em vários subdominios;
- Diminiua o uso de iframes – iFrames exigem novas requisiçõ~es com subrequisições, deixando a página consideravelmente lenta;
- Mantenha seus componentes abaixo de 25kb.
Otimização de CSS
- Use css sprites;
- Coloque os arquivos no topo do documento;
- Evite expressões no CSS;
{background-color: expression((new Date().getHours()%2 ? “#00000” : “#FFFFF”))}
- Use arquivos externos (evite inline e tag style);
- Prefira <link> ao invés de @import – Utilizando <link> você pode aproveitar o paralelismo dos navegadores, com o @import não.
Carregamento modular js
Utilizamos o carregamento modular do js quando precisamos de mais performance e organização. Através do carregamento modular, podemos carregar apenas os arquivos, funções ou classes específicas que iremos usar. Para isso, podemos utilizar o Require JS.
Vantagens:
- Carregamento otimizado, não precisamos carregar tudo;
- Podemos carregar apenas uma função ou classe;
- Integrado com NodeJs;
- Jquery incorporado;
- UglifyJS para comprimir e unificar todos os js requeridos.
O requireJS trabalha de forma simples, apenas uma função chamada “require(“file”, function)”. O grande diferencial é que o arquivo será carregado somente quando você precisar.
require(["jquery", "jquery.alpha", "jquery.beta"], function($) {
//the jquery.alpha.js and jquery.beta.js plugins have been loaded.
$(function() {
$('body').alpha().beta();
});
});
HTML5 Boilerplate
O HTML5 boilerplate é um conjunto de boas práticas para você iniciar o seu projeto otimizado em HTML5. Com ele você tem um arquivo .htaccess totalmente configurado para trabalhar da melhor maneira possível, além disso também contamos com:
- Suporte cross-browser;
- Compatibilidade com browsers legados;
- Estrutura padrão de um documento HTML5 otimizado;
- Estrutura padrão para criação de plug-ins js;
- Estutura padrão para css cross-browser.
Ferramentas de diagnóstico
Com as ferramentas de diagnóstico, podemos saber como está o fluxo de nossas aplicações, além de sabermos exatamente quais arquivos ou recursos estão deixando o site lento. Aqui vai uma lista dos mais populares:
- Chrome DeveloperTools – Para debugação do js, analise de recursos e elementos;
- WebPagetest – Executa diversas validações e testes de performance, além disso fala o que seria ideal fazer para resolver os problemas;
- Firebug – Para debugação do js, analise de recursos e elementos;
- GzipTest – Verifica se determinado domínio usa compressão GZIP;
- HTTP Analysis Tools – Diversas ferramentas de analise, como compressão, cache, invalid caches;
- Page Speed – Verifica se sua aplicação segue as diretrizes de um site otimizado.
Conclusão
Eessas são algumas das estratégias utilizadas para otimizarmos nossas aplicações e todas estão disponíveis com mais detalhes no yahoo developers. Caso alguém conheça outras estratégias, por favor compartilhe conosco nos comentários. A intenção desse artigo é divulgar boas práticas!