Como aumentar o desempenho de seu site – Épico!

Atualizado em 04/11/2017!

O artigo de hoje traz inúmeras dicas de como aumentar a performance dos seus sites, independentes de qual plataforma eles executam ou em qual linguagem eles são desenvolvidos. No final das contas tudo vira HTML e a comunicação é feita via protocolo HTTP.

Existem muito mais dicas do que as apresentadas aqui, listei apenas as de uso mais comum e que se aplicam à maioria dos sites. Muitas destas dicas somente fazem efeito quando seu site possui um número expressivo de acessos, então não espere que seu blog desconhecido mostre sinais de super desempenho ao utilizar quaisquer das dicas abaixo.

Por que você deveria se preocupar com a velocidade do seu site? Dê uma lida nesse post onde apresento ótimos argumentos.

As dicas estão divididas em categorias:

  1. Reduza as requisições HTTP
  2. Utilize os cabeçalhos Expires e Cache-Control
  3. Componentes GZip
  4. Folhas de estilo no início
  5. Scripts no Final
  6. Use CSS e JavaScript externos
  7. Minimize JavaScript e CSS
  8. Carregue componentes após o load
  9. Carregue componentes antes do load
  10. Divida componentes entre domínios
  11. Fora 404!
  12. Otimize as imagens
  13. Otimize seus CSS Sprites
  14. Use um CDN
  15. Use as versões mais recentes das tecnologias do seu site

Vamos lá!

#1 – Reduza as requisições HTTP

80% do tempo de resposta ao usuário final é gasto na apresentação do site (front-end). A maioria deste tempo é perdido baixando todos os componentes na página: imagens, folhas de estilo, scripts, Flash, etc. Reduzindo o número de componentes reduz por sua vez o número de requisições HTTP necessárias para renderizar a página. Esta é a chave para páginas mais velozes.

Uma vez que você reduza o número de componentes na página você estará simplificando o projeto da mesma. Mas existe alguma maneira de criar páginas com conteúdo rico enquanto mantém tempos curtos de resposta? Existem algumas técnicas para reduzir o número de requisições HTTP, enquanto se preserva os projetos de páginas ricas.

Arquivos combinados são uma maneira de reduzir o número de requisições HTTP combinando todos os scripts em um único arquivo de scripts, e similarmente combinando todos os CSS em uma única folha de estilos. Combinar arquivos é bem desafiador quando os scripts e folhas de estilo variam de página para página, mas fazê-lo antes de lançar seu site vai melhorar o tempo de resposta das páginas.

CSS Sprites são o método preferido para reduzir o número de imagens requisitadas. Combine suas imagens de fundo em uma única imagem e use as propriedades de CSS background-image e background-position para exibir o segmento desejado da imagem.

Image maps combinam múltiplas imagens em uma única imagem. O tamanho total será o mesmo, mas reduzirá o número de requisições HTTP, acelerando a página. Image maps somente funcionam se as imagens são contíguas na página, como uma barra de navegação. Definir as coordenadas de image maps pode ser monótona e com chance de erro. Usar image maps para navegação não é acessível também, logo não é recomendado.

Inline images usam o esquema data: URL para embutir os dados da imagem na página atual. Isto pode aumentar o tamanho de seu HTML. Combinar inline images dentro de suas folhas de estilo (armazenadas em cache) é uma maneira de reduzir as requisições HTTP e prevenir o aumento de tamanho de suas páginas. Inline images também não são suportadas na maioria dos browsers.

Reduzir o número de requisições HTTP na sua página é a primeira coisa a se fazer quando o assunto é performance. É a parte mais importante de uma otimização de desempenho quando estamos falando de visitantes de primeira viagem. Os números de diversas pesquisas indicam que 40-60% dos visitantes diários de seu site estão com o cache vazio. Tornar a sua página rápida para estes visitantes de primeira viagem é a chave para uma melhor experiência do usuário.

#2 – Utilize os cabeçalhos Expires e Cache-Control

Existem dois aspectos para esta regra:

  • Para componentes estáticos: implemente a política “Never expire” configurando o cabeçalho Expires para um futuro distante
  • Para componentes dinâmicos: use um cabeçalho Cache-Control apropriado para ajudar o browser com requisições condicionais

Projetos de Web pages estão se tornando cada vez mais ricos, o que significa mais scripts, folhas de estilo, imagens e animações na página. Um visitante de primeira viagem que chegar na sua página terá de realizar diversas requisições HTTP, porém utilizando o cabeçalho Expires você pode tornar estes componentes armazenáveis em cache. Isto previne requisições HTTP desnecessárias em visualizações de página subsequentes. Os cabeçalhos Expires são muitas vezes utilizados com imagens, mas eles devem ser usados em todos componentes incluindo scripts, folhas de estilo e componentes Flash.

Browsers (e proxies) usam cache para reduzir o número e tamanho das requisições HTTP, tornando o carregamento das páginas mais rápido. Um webserver utiliza o cabeçalho Expires na resposta HTTP para dizer ao cliente por quanto tempo um componente pode ser armazenado em cache. Este é um cabeçalho com expiração muito distante, dizendo ao browser que esta resposta não deve ser removida de cache até 15 de abril de 2012.

Se o seu servidor é Apache, use a diretiva ExpiresDefault para definir uma data de expiração relativa à data atual. Este exemplo de diretiva ExpiresDefault define a data de expiração para daqui a 10 anos, a partir do instante da requisição.

Tenha em mente, se você usar um cabeçalho para expiração futura você terá de trocar o nome do arquivo do componente toda vez que o componente for alterado. Geralmente as empresas o fazem como parte do processo de lançamento de uma nova versão do site: um número de versão do arquivo é incluído no nome do arquivo, por exemplo, luiztools_2.0.6.js.

Usar um cabeçalho de expiração futura afeta somente as visualizações de página feitas depois da primeira visita do usuário ao seu site. Não há efeito algum quando o usuário visita seu site pela primeira vez e o cache do browser está vazio. Entretanto o impacto desta melhoria de performance depende de quantas vezes os usuários acessam suas páginas com o cache cheio. Através do uso do cabeçalho Expires, você aumenta o número de componentes que são armazenados em cache pelo browser e re-utiliza em subsequentes visualizações de página sem enviar um único byte através da conexão de Internet.

#3 – Componentes GZip

O tempo de transferir uma requisição e uma resposta HTTP pela rede pode ser significativamente reduzido por decisões feitas no front-end do webmaster. É verdade que a largura de banda do usuário-final, provedor de Internet, proximidade dos roteadores, etc. estão além do controle do time de desenvolvimento. mas há outras variáveis que afetam os tempos de resposta. A compressão reduz os tempos de resposta diminuindo o tamanho da resposta HTTP.

Iniciando com HTTP/1.1, os clientes web indicam suporte à compressão com o cabeçalho Accept-Encoding na requisição HTTP.

Se o servidor web vê este cabeçalho na requisição, ele pode comprimir a resposta usando um dos métodos listados pelo cliente. O servidor web notifica o cliente web disto via cabeçalho Content-Encoding na resposta.

Gzip é o método de compressão mais popular e efetivo atualmente. Ele foi desenvolvido pelo projeto GNU e padronizado pela RFC 1952. Outro método de compressão existente é o deflate, mas ele é menos eficiente e menos popular.

Gzipar geralmente reduz o tamanho da resposta em cerca de 70%. Aproximadamente 90% do tráfico atual de Internet que viaja através dos browsers suportam gzip. Se você usa Apache, o módulo de configuração do gzip depende de sua versão: Apache 1.3 usa mod_gzip enquanto Apache 2.x usa mod_deflate.

Existem problemas conhecidos com browsers e proxies que podem causar problemas com compressão HTTP, felizmente estes problemas estão restritor à usuários de browsers antigos.

Servidores escolhem o que será comprimido, baseado no tipo de arquivo. tipicamente eles são bem limitados e a maioria dos sites somente zipa seus documentos HTML. Também é possível zipar seus scripts e stylesheets, mas muitos sites perdem essa oportunidade. Na verdade é possível comprimir qualquer texto incluindo XML e JSON. Imagens e arquivos PDF não devem ser zipados porque eles já estão em formatos comprimidos. Tentar diminuir ainda mais seu tamanho não somente irá gastar CPU à toa como pode aumentar o tamanho dos arquivos.

Gzipar todos os arquivos possíveis é uma maneira fácil de reduzir o peso das páginas e acelerar a experiência do usuário..

#4 – Folhas de Estilo no Início

Colocar as folhas de estilo no HEAD  do documento faz com que as páginas pareçam estar carregando mais rápido. Isto se deve ao fato de que colocando as folhas de estilo no topo da página permite que ela se renderize progressivamente.

Especialistas em front-end que cuidam de performance querem que uma página carregue progressivamente; isto é, nós queremos que o browser exiba algum conteúdo o mais rápido possível. isto é especialmente importante para páginas com um monte de conteúdo e para usuários com internet ruim. A importância de dar aos usuários um feedback visual, como indicadores de progresso, é largamente pesquisada e documentada. No caso de páginas web, a própria renderização da página é o melhor indicador de progresso! Quando o browser carrega a página progressivamente o usuário vai assistindo sua construção: o cabeçalho, a barra de navegação, o logo, etc. tudo serve como feedback visual para o usuário que está esperando pela página. Isto melhora bastante a experiência do usuário.

O problema em colocar as folhas de estilo próximas ao rodapé do documento é que isto proíbe a renderização progressiva em muitos browsers, incluindo o Internet Explorer. estes browsers bloqueiam a renderização para redefinir o redesenho de elementos na página, caso seus estilos sejam alterados. O usuário fica vendo uma tela em branco.

A especificação HTML claramente diz que as folhas de estilo devem ser incluídas no HEAD da página: “Diferente de A, [LINK] deve somente aparecer na seção HEAD de um documento, embora ele possa aparecer inúmeras vezes.” Obter uma tela branca ou fazer a tela piscar sem estilo não valem este risco. A melhor solução é seguir a especificação HTML e carregar suas folhas de estilo no HEAD do documento.

#5 – Scripts no Final

O problema dos scripts é que eles bloqueiam downloads paralelos. A especificação HTTP/1.1 sugere que os browsers não baixem mais de dois componentes em paralelo por hostname. Se você obtém suas imagens de múltiplos hostnames, você pode obter mais de dois downloads simultâneos. Entretanto, quando um script está sendo baixado, o browser não pode iniciar outros downloads, mesmo em diferentes servidores.

Em algumas situações não é fácil mover os scripts para o final da página. Se, por exemplo, o script usar document.write para inserir parte do conteúdo da página, ele não pode ser movido para baixo da mesma. Podem existir problemas de escopo também. Em muitos casos, existem maneiras para contornar esta situação.

Uma sugestão alternativa é utilizar scripts deferidos (deferred). O atributo DEFER indica que o script não contém document.write, e é uma dica aos browsers para que eles continuem renderizando. Infelizmente, o Firefox não suporta o atributo DEFER. No Internet Explorer, o script pode ser deferido, mas não tanto quanto desejado. Se o script puder ser deferido, ele também pode ser movido para o final da página. Isto faz com que suas páginas carreguem mais rápido..

#6 – Use CSS e JavaScript externos

Muitas dessas regras de performance lidam com como os componentes externos são gerenciados. Entretanto, antes dessas considerações surgirem você deve perguntar uma questão ainda mais básica: o Javascript e CSS devem estar em arquivos externos ou na própria página?

Usar arquivos externos no mundo real geralmente produz páginas mais rápidas porque estes arquivos são mantidos em cache pelo browser. JavaScript e CSS que estão escritos no HTML são baixados cada vez que o documento é requisitado. Isto reduz o número de requisições HTTP que são necessárias, mas aumenta o tamanho do documento HTML. Por outro lado, se o JavaScript e o CSS estão em arquivos externos em cache no browser, o tamanho do HTML é reduzido sem aumentar o número de requisições HTTP.

A chave, então, é a frequência cujos componentes externos são mantidos em cache relativo ao número de documentos HTML requisitados. Este fator, embora difícil de quantificar, pode ser analisado usando várias métricas. Se os usuários de seu site tem muitos pageviews por sessão e muitas de suas páginas reusam os mesmos scripts e estilos, há um grande potencial de ser beneficiado pelo cache de arquivos externos.

Muitos web sites caem no meio dessas métricas. Para estes sites, a melhor solução geralmente é usar JavaScript e CSS em arquivos externos. A única exceção fica para as home pages, onde escrever o código JS e CSS é preferível. Home pages que possuem poucos (quase sempre um) page view por sessão pode encontrar resultados mais rápidos escrevendo JS e CSS no próprio HTML.

#7 – Minimize JavaScript e CSS

Minificação é a prática de remover caracteres desnecessários do código para reduzir seu tamanho, melhorando tempos de carregamento. Quando o código é minificado todos os comentários são removidos, bem como espaços em branco desnecessários. No caso de JavaScript, isto melhora a performance porque seu tamanho é reduzido e consequentemente o tempo de download também. Duas ferramentas populares para minificar JavaScript são JSMin e YUI Compressor. O YUI Compressor também pode minificar CSS.

Ofuscação é uma alternativa de otimização que pode ser aplicada ao código fonte. Ela é mais complexa que minificação e algumas vezes gera bugs como resultado da ofuscação. Em uma pesquisa americana notou-se que códigos minificados obtém 21% de redução d etamanho, contra 25% da ofuscação. Embora a ofuscação mostre um desempenho melhor, minificar o JS tem menos risco.

Em adição à minificação de scripts e estilos, tags

Uma alternativa em PHP seria criar uma função chamada inserirScript.

Além de prevenir que o mesmo script seja inserido múltiplas vezes, esta função pode gerenciar outros problemas com scripts, como checagem de dependência e tudo o mais que sua imaginação permitir.

#8 - Carregue componentes após o load

Você deve olhar para sua página e se questionar: "O que é absolutamente necessário para que a página renderize?". O resto do conteúdo e dos componentes podem esperar.

JavaScript é um candidato ideal para ser carregado depois do evento load. Por exemplo se você tem um código JavaScript para fazer animações em botões, eles podem esperar, porque as animações só vão fazer sentido depois que toda página tiver sido renderizada. Outros locais a se dar uma olhada incluem conteúdo oculto (conteúdos que aparecem somente após alguma interação do usuário) e algumas imagens que não são visualizadas em um primeiro momento.

Para fazer com que imagens sejam carregadas somente quando estejam visíveis (ou próximas de estarem visíveis), sugiro o uso do plugin Lazy Load.

É bacana quando os objetivos de performance estão alinhados com as melhoras práticas web. Neste caso, a idéia de aperfeiçoamentos progressivos nos diz que Javascript, quando suportado, pode melhorar a experiência do usuário, mas você tem que ter certeza de que a página funciona mesmo sem JavaScript. Então depois que tiver certeza disso, você pode aperfeiçoar ela com alguns scripts pós-carregados que dêem mais recursos à página, como botões animados.

#9 - Carregue componentes antes do load

Pré-carregar pode ser entendido como o oposto de Pós-carregar, mas na verdade ele possui um objetivo diferente. Pré-carregar componentes lhe dá uma vantagem sobre o tempo ocioso do browser, quando ele poderia, por exemplo, estar carregando imagens que serão usadas futuramente. A idéia é quando o usuário troque de página, ele tenha uma experiência ainda mais rápida do que na primeira página.

Existem vários tipos de pré-carregamento:

  • Não-condicional: assim que o load inicia, vá em frente e carregue uns componentes extras. O site do Google utiliza esta técnica, carregando todas imagens através de CSS Sprite que serão usadas nas páginas seguintes (página de resultados, por exemplo)
  • Condicional: baseado na ação do usuário você faz um palpite do que o usuáro está pensando e já carrega os próximos componentes. O Yahoo usa esta técnica na caixa de busca deles, carregando alguns componentes conforme o que o usuário digita na caixa de busca.
  • Antecipado: esta técnica é utilizada quando você está pensando em trocar o layout do seu site em breve. Geralmente você ouve coisas do tipo "Muito legal o novo site do fulano, mas o antigo era mais rápido.". Isso acontece porque o site antigo já estava com os elementos em cache, como imagens, JS e CSS, enquanto que no novo site tudo teve de ser baixado. O pré-carregamento antecipado consiste em fazer com que seus visitantes do site antigo já baixem alguns componentes e deixem-os em cache no navegador, para quando o novo site for pro ar, a transição seja mais suave. Faça isso linkando CSS e JS antecipados, alguns dias antes do lançamento. Colocar algumas imagens sobrepostas também pode ajudar.

#10 - Divida componentes entre domínios

Dividir os componentes entre domínios pode maximizar o download paralelo de componentes. Garanta que não está usando mais do que 2-4 domínios por causa do tempo de resolução de DNS ou a técnica sairá pela culatra. Por exemplo, você pode hospedar seu HTML e conteúdo dinâmico em www.teste.com.br e dividir componentes estáticos ente img.teste.com.br e css-js.teste.com.br.

#11 - Fora 404!

Requisições HTTP são recursos "caros" à performance de um site o que torna uma imensa burrice permitir erros 404 em seu site por preguiça ou ignorância.

Alguns sites possuem páginas 404 bacanas que ajudam o usuário a encontrar o que não acharam na URL acessada, entretanto, mesmo estas páginas consomem recursos do servidor. Pior ainda é quando os erros 404 são causados por links de JS e CSS quebrados. No primeiro caso, além de gerar uma custosa requisição, o carregamento do restante da página irá travar até que o referido erro aconteça porque o download de javascript não permite outros downloads em paralelo. Como se não fosse o bastante, muitos browsers tentarão ler a página 404 procurando algum script útil pois buscavam um arquivo de scripts...

 

#12 - Otimize as imagens

Depois que o designer tenha terminado de criar as imagens para sua página, existem ainda algumas coisas que você pode fazer antes de enviar as imagens para seu servidor.

  • você pode verificar os GIFs e ver se eles estão usando um tamanho de paleta correspondente ao número de cores na imagem. Usando o software ImageMagick é fácil de verificar com o comando: identify -verbose imagem.gif. Quando você ver que uma imagem está usando 4 cores e uma palheta de 256 cores, há espaço para melhoria.
  • Tente converter GIFs para PNGs e ver se há alguma economia. Geralmente tem. Desenvolvedores muitas vezes hesitam em usar PNGs devido ao suporte limitado nos browsers, mas isto é coisa do passado. O único problema real é a transparência-alfa em PNGs true color, mas novamente, GIFs não são true color e não suportam transparência variável. Então qualquer coisa que um GIF possa fazer um PNG também faz (exceto animações). Este simples comando do ImageMagick gera PNGs seguros para usar: convert image.gif image.png
  • Execute o aplicativo pngcrush (ou qualquer outro otmizador de PNG) em todos seus PNGs, por exemplo, com este comando: pngcrush imagem.png -rem alla -reduce -brute resultado.png
  • Execute o aplicativo jpegtran em todos seus JPEGs. Esta ferramenta faz operações sem perdas em JPEGs como rotação e também pode ser usada para otimizar e remover comentários e outras informações inúteis (como informações EXIF) em suas imagens. Ex: jpegtran -copy none -optimize -perfect imagem.jpg destino.jpg
  • se estiver usando WordPress, use o excelente plugin EWWW Image Optimizer que permite usar recursos de diferentes algoritmos de compressão na sua pasta de mídias com apenas um clique
  • no desktop, use o software ImageOptim que é excelente para executar diversos algoritmos de compressão lossless e lossy em suas imagens, conforme quiser. É muito fácil de usar, basta arrastar as imagens para a janela dele e mandar converter.
ImageOptim
ImageOptim

Uma outra dica sobre otimização de imagens é não escalar imagens no HTML. Não use uma imagem grande que você precise definir a largura e altura dela em HTML. Se você precisar fazer isso:

então sua imagem (meucachorro.jpg) deve ter o tamanho de 100x100px ao invés redimensionar uma imagem de 500x500px, por exemplo.

#13 - Otimize seus CSS Sprites

Aqui vão algumas dicas que deixarão seus sprites ainda mais otimizados:

  • organizar as imagens no sprite horizontalmente ao invés de verticalmente resultará em arquivos menores
  • combinar cores similares em uma sprite lhe ajuda a manter a contagem de cores baixa, idealmente abaixo de 256 cores para que se encaixe em um arquivo PNG8.
  • não deixe grandes espaços entre as imagens do sprite. Isto não afeta muito o tamanho do arquivo mas requer menos memória do usuário para descomprimir a imagem em um mapa de pixels. Uma imagem 100x100 tem 10 mil pixels, enquanto uma 1000x1000 tem um milhão.

#14 - Use um CDN

As redes de entrega de conteúdo (CDNs) como a Cloudflare e o AWS Cloudfront são excelentes para turbinar a velocidade de entrega dos seus arquivos estáticos, especialmente se você tem muitos acessos de fora do país onde seu site está hospedado. Se você usa a hospedagem da Umbler, basta ativar o add-on gratuito da Cloudflare no seu painel de controle.

Um provedor de CDN nada mais faz do que uma cópia de todos seus arquivos estáticos em diversos servidores espalhados pelo mundo. Assim, quando um usuário requisita um desses arquivos no seu site, ele entrega a cópia que está mais perto do usuário, fornecendo uma entrega mais rápida.

#15 - Use a versão mais recente das tecnologias do site

Entre uma versão e outra de tecnologias famosas como PHP, .NET e Node.js muitas das melhorias são de desempenho, pois as aplicações e sites web estão cada vez mais exigentes. Sendo assim, usar a versão mais recente da sua plataforma de desenvolvimento não é apenas uma questão de estar na vanguarda, mas sim de tirar o máximo proveito da tecnologia que seu site usa.

Isso é especialmente verdade na plataforma WordPress por exemplo (a que eu uso para este blog). Não apenas você deve manter seu WordPress atualizado (por uma questão de segurança), mas também o seu PHP. Depois que mudei para a versão 7 do PHP meu blog ficou muito mais rápido e consumindo menos recursos do meu plano de hospedagem.

O mesmo é válido para .NET, se você puder migrar para ASP.NET Core, que está estupidamente mais leve e veloz que o framework tradicional.

E por fim, o Node.js nas novas versões (8+) tem usado recursos mais modernos do motor de JavaScript V8 do Google que o deixaram ainda mais poderoso.

Posts complementares a esse são:

E você, tem alguma dica de performance que eu não listei aqui?

O que achou desse artigo?
[Total: 2 Média: 5]