Como melhorar a velocidade do seu site – Guia Completo de Boas Práticas

[Dicas, Técnicas e Ferramentas]

Usuários querem acessar sites que carreguem rapidamente, ainda mais com o número crescente de usuários que acessam sites através de dispositivos móveis, a otimização está se tornando uma parte crucial da experiência do usuário.

Sites podem ser lentos por uma série de razões, entre elas: HTML, CSS e JS mal otimizados, requisições desnecessárias no servidor, imagens não compactadas, etc.

Um site rápido aumenta a experiência e a usabilidade dos usuários!


Preparando o terreno

  • Chrome tem uma excelente ferramenta para análise. Na DevTools, na aba Network você encontra um mundo de informações sobre o desempenho das suas páginas.
  • Use ferramentas online e plugins como GTmetrix, PageSpeed Insights (versão online), PageSpeed Insights (Plugin Chrome) para testar o tempo de carregamento das suas páginas a partir de um servidor real.
  • Há um projeto chamado Browser Calories que calcula de uma maneira divertida o quanto pesa um determinado site e compare se ele está bem ou mal em relação aos top 100 sites do mundo.
  • Utillize um Automatizador de Tarefas, tipo o Grunt. Com ele você pode minificar, concatenar arquivos, ofuscar scripts e muito mais.

Servidor

Reduzir o tamanho dos arquivos ajuda melhorar o tempo de carregamento e também economizar largura de banda.

Ordem de carregamento

Heat Map Generator é uma ferramenta online que mostra um print passo a passo do carregamento do seu site. Você consegue ver exatamente a ordem de carregamento dos elementos na própria página.

Compressão GZIP

Medida muito eficaz que otimiza o tempo de carregamento é ativar a compactação GZIP no seu servidor de hospedagem. Em média, você pode ter um arquivo reduzido em 70% usando a compressão GZIP.

GZIP funciona em todos os navegadores modernos e compacta os arquivos JavaScript, CSS, HTML, XML, SVG, Respostas JSON. Verifique com a ferramenta Check Gzip Compression se o GZIP está ativo no servidor

Ativação do GZIP em um servidor APACHE é feita inserido um código no seu .htaccess.

Exemplo:
<ifModule mod_gzip.c>
 mod_gzip_on Yes
 mod_gzip_dechunk Yes
 mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
 mod_gzip_item_include handler ^cgi-script$
 mod_gzip_item_include mime ^text/.*
 mod_gzip_item_include mime ^application/x-javascript.*
 mod_gzip_item_exclude mime ^image/.*
 mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>

Use o cache do navegador

Isto faz com que os navegadores não precisem baixar as coisas mais de uma vez.

Crie cache para os arquivos: JS e CSS, imagens, PDFs para ficarem armazenadas no navegador do usuário.

Exemplo:
## EXPIRES CACHING ##
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType text/html "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType text/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 1 month"
</IfModule>
## EXPIRES CACHING ## 

Evite Redirecionamentos

Muitas vezes usado para evitar links quebrados o redirecionamento HTTP é conveniente para preservar o tráfego. Porém, usado incorretamente pode causar problemas de desempenho. Então tome cuidado com redirecionamentos desnecessários.

Não faça redirecionamento com JS usando window.location.

HTML

Código HTML bem trabalhado e estruturado é uma premissa crucial para criação de páginas com carregamento rápido

Profundidade do código

Quando produzir seu código HTML, é importante que você o deixe o mais simples possível. Quanto menos profundidade existir mais rápido seu HTML será executado pelo Navegador.

Essa profundidade do código HTML influencia a complexidade dos seletores CSS. Quando fizemos um seletor muito profundo o Navegador leva mais tempo para encontrar o elemento

Exemplo:
<nav class="menu">
 <div class="menu-inner">
    <ul class="menu-list">
       <li><a href="#">...</a></li>
    </ul>
 </div>
</nav>

HTML mais otimizado:

<nav class="menu">
  <ul class="menu-list">
    <li><a href="#">...</a></li>
  </ul>
</nav>

Minifique

Técnica que compacta arquivos HTML, CSS e JS, removendo caracteres desnecessários, comentários, espaços, quebras de linha.

HTML Minifier é uma ferramenta online. Há também o Plugin Minifier para o Sublime Text e a ferramenta JS-minifier que renomeia as variáveis e nome de funções para nomes menores.

Combine chamadas JS e CSS

Cada solicitação HTTP para o servidor tem um custo. Reduza o número de requisições do servidor, junte vários arquivos JavaScript e CSS em apenas um. O exemplo abaixo mostra com arquivos JavaScript, use a mesma técnica para o arquivos CSS.

Exemplo:
<script src="/scripts/jquery.min.js"></script>
<script src="/scripts/application.js"></script>
<script src="/scripts/ui/minified/jquery.ui.all.min.js"></script>
<script src="/scripts/all.js"></script>

CSS no topo JS no rodapé

Insira seu CSS dentro do <head>. Quando fizemos isso o navegador renderiza a página de forma progressiva. Dando a impressão que a página está carregando mais rápida.

JavaScript bloqueia a renderização de tudo que vem abaixo dele. Por isso, ponha suas chamadas no rodapé da página, antes do elemento </body>.

Progressivamente

Use HTML, em seguida, vá para o CSS e quando necessário passe para JavaScript. Por exemplo: em muitos casos, é possível usar HTML para validação de formulário e CSS ou SVG para animação (sem recorrer ao JavaScript).

Class/id no elemento pai

Sempre que possível, utilize class/id no elemento pai e não no elemento filho.

Exemplo:
<ul class="ingredients">
  <li>Basil</li>
  <li>Pine nuts</li>
  <li>Garlic</li>
</ul>

Valide o HTML

Utilize ferramentas de validação para seu HTML. Exemplo, HTMLhint.

Não use @import

Utilizar @import na tag <head> perdemos performance, essa chamada tem um comportamento mais lento. Quando utilizamos @import dentro de um arquivo .CSS o navegador não consegue realizar o download dos arquivos CSS ao mesmo tempo.

Essa diretiva tem um impacto negativo no desempenho das páginas. Use sempre a tag <link>, assim o navegador faz o download das folhas de estilos (caso tenha mais que uma) em paralelo.

CSS

Quando o navegador encontra na sua análise uma chamada CSS, ele deve fazer a requisição do servidor e esperar o arquivo baixar para depois construir o CSSOM Isso aumenta o tempo de carregamento do restante dos componentes.

CSS não imagem

Muita coisa hoje pode ser feito com CSS. Sempre que possível use CSS no lugar de imagens. Contudo, tome cuidado com a compatibilidade entre navegadores. Lembre-se de consultar o Can I use para ver o suporte aos navegadores.

CSS crítico primeiro

Carregue o conteúdo da parte crítica da sua página imediatamente. Insira o CSS responsável por estilizar a parte crítica diretamente no HTML, dentro da tag <style>.

Chamamos de parte crítica (ou conteúdo acima da dobra) tudo aquilo que o usuário vê sem dar scroll para baixo.

Utilize ferramentas que lhe mostrem as regras de estilo que devem ser carregadas diretamente na página HTML: PentHouse e tem a versão online também Critical Path CSS Generator

CSS Assíncrono

Agora que o CSS crítico já está <head>,chame seus estilos externos de forma assíncrona. Essa tarefa é fácil com loadCSS .

Exemplo:
<head>
  <style>
    /* CSS crítico inline  */
  </style>
  <script>
   // script que chama a função loadCSS
   function loadCSS( href, before, media, callback ){ ... }
   // carrega sua folha de estilos
   loadCSS("/path/to/stylesheet.css");
  </script>
  <noscript>
    <link href="/path/to/stylesheet.css" rel="stylesheet">
  </noscript>
</head> 

Consulte também uma sugestão de Otimização de Requisições CSS do Google.

WebFonts

Ao carregar uma página, especialmente em conexões móveis, você pode ter notado o texto se tornar invisível por um período de tempo.

Quando um navegador tenta baixar um tipo de letra web, ele esconde o texto por um período de tempo até que ele termine de baixar a fonte e está pronto para exibir o texto.

Uma solução é carregar as fontes progressivamente, primeiro contando com as fontes do sistema (Helvetica, Geórgia...). de forma assíncrona usando loadCSS (descrito no item anterior) e depois com a ajuda da biblioteca Font Face Observer para detectar quando as fontes foram baixadas. Depois das fontes baixadas, uma classe é adicionada ao documento que define a fonte.

Exemplo:
<head>
  <style>
    body { font-family: Helvetica, Arial, sans-serif; }
    .fonts-loaded body { font-family: Roboto, Helvetica, Arial, sans-serif; }
  </style>
  <script>
    // chamada do CSS assíncrono
    function loadCSS( href, before, media, callback ){ ... }
    // chamada de fontes de forma assíncrona
    loadCSS("//fonts.googleapis.com/css?family=Roboto:400,500,700");
    // Função da biblioteca FontFaceObserver
    (function(){ ... }
    // detecta o carregamento das fontes
    var roboto400 = new FontFaceObserver("Roboto", {
      weight: 400
    });
    var roboto700 = new FontFaceObserver("Roboto", {
      weight: 700
    });

    Promise.all([
      roboto400.check(),
      roboto700.check()
    ]).then(function() {
      document.documentElement.className += " fonts-loaded";
    });
  </script>
</head> 

Faxina no CSS

Elimine o que não é usado: use a ferramenta CSSstats para analisar suas regras e remover o que não está sendo usado.

Use a ferramenta de Auditoria do Chrome. Ela é capaz de mostrar as regras CSS não usadas na página auditada.

Exemplo:
Auditoria de CSS no no Chrome

Aba "Audits" DevTools do Chrome

JavaScript

Ao inserir um script o navegador aguarda o download completo e execução desse script para depois continuar a renderização do restante da página.

Pense em não usar jQuery

Não há dúvidas que usar jQuery e seus plugins torna a vida muito mais fácil, porém antes de usar pare por um momento para considerar se realmente você precisar usar jQuery.

Quero dizer que muita coisa pode ser feita com JavaScript puro. Consulte uma comparação no site You Might Not Need jQuery de código jQuery e seu equivalente JavaScript.

Caso você realmente precise usar jQuery, use sua versão minificada e sua última versão. Bibliotecas de código aberto como o jQuery ficam mais rápidas e mais leve à medida que vão sendo atualizadas.

Atributo async & defer

Informe ao navegador para baixar seu script independente do HTML. Assim liberamos o navegador para baixar outros recursos enquanto o script é carregado. Para isso adicione o atributo async à chamada do seu script no HTML. Assim, o download do script é feito de forma assíncrona.

  • Atributo async: O script é executado de forma assíncrona. O Script é executado após o download do arquivo.
  • Atributo defer: Executa o script após a página carregar.
Exemplo:
<script src="scripts.js" async></script> 

Mas atenção! Utilize async no seu script apenas se ele não vai executar mudanças na árvore do DOM.

Evite manipular o DOM

Manipular o DOM, animando, incluindo e removendo classes e muito mais, é uma tarefa simples, ainda mais com uso de jQuery por exemplo. Navegar pelo DOM é algo trabalhoso para o navegador, principalmente se isso for feito no momento que toda página é carregada. Antes de mexer no DOM tenha a certeza que é a única saída.

Imagens

Otimizar, entregar o melhor arquivo e formato de imagem resulta em uma grande melhora no desempenho das suas páginas.

De acordo com o HTTParchive, as páginas têm em média 1860KB, sendo que desse total 1180KB (63%) são imagens.

Escolha o formato

Escolha o formato de imagem mais apropriado. Aqui faça testes e escolha qual a melhor qualidade, com e sem perdas na qualidade final do arquivo.

Exemplos:
Formato Descrição
GIF
  • Transparência;
  • Utilize somente se é preciso animação.
PNG
  • Aceita transparência;
  • Mantém todos os detalhes da imagem, por isso seu tamanho costuma ser maior.
JPG
  • Utilize para fotos e captura de telas.
WebP
  • Oferece melhor compactação e mais recursos;
  • Como nem todos navegadores ainda dão suporte a esse tipo de arquivo, podemos criar um algoritmo no lado do servidor que verifica o suporte do navegador.
DataURI
  • Permite colocar pequenas imagens inline no CSS ou HTML;
  • Imagem é incorporada à página, assim não há necessidade de fazer requisição da imagem.

Defina largura e altura

Defina a largura e altura das imagens, isso reduz o tempo de renderização. Dessa forma o navegador reserva um espaço para imagem. Após o download da imagem o navegador não precisa empurrar os outros elementos para alocar a imagem

Exemplo:
<img width="120" height="80" src="logo.jpg" alt="Logo" /> 

Mas atenção! não transforme, por exemplo, uma imagem de 500 X 500px em 50 X 50px. O seu tamanho em KBs será o mesmo.

Diminua a qualidade

Você também pode espremer bytes de suas imagens baixando a qualidade da imagem. A maioria das imagens ao ser exportadas com qualidades entre 82-92% ficam ainda com uma qualidade ainda muito boa.

Baixe a qualidade, com uma qualidade aceitável que não mostre as imperfeições da imagem.

Compressive Images

Técnica usada em imagens JPG que consiste em duplicar o tamanho da imagem, mas com 0% de qualidade e redimensionar essa imagem pelo HTML. Com isso reduzimos o peso da imagem aumentando a profundidade de bits; ótimo para usar em uma tela de retina e não-retina. Para saber mais leia o Artigo sobre Telas Retina.

Exemplos:
Imagem Original
Imagem original

Tamanho 83.2kb

Qualidade de 0%
Imagem compactada

Tamanho da imagem 75.3kb

Lazy Loading Images

Utilizada para carregar conteúdos mais pesados - Imagens por exemplo - apenas quando estão na área visível da janela do Navegador. Para aplicar Lazy Loading consulte o artigo Lazy Load Plugin for jQuery.

Veja um Exemplo da Técnica. Perceba que o navegador faz o download apenas quando a imagem está na área visível da tela. Abra a DevTolls do Chrome e vá até aba elementos.

CSS Sprites

Combinar várias imagens em uma só, a fim de reduzir solicitações HTTP e melhorar o tempo de carregamento da página. Use CSS para exibir apenas a área que você deseja.

CSS Sprite

CSS Sprite

Algumas ferramentas online para CSS sprite: InstantSprite e SpritEpad.

Elemento Picture

Servir uma mesma imagem e grande para todos dispositivos pode ter um impacto negativo no quesito desempenho. Felizmente, o elemento picture permite que os desenvolvedores utilizem diferentes imagens e tamanhos para diferentes dispositivos baseados em sua largura.

Exemplo:
<picture>
   <source media="(min-width: 1024px)" srcset="dest/1024/tiger.jpg">
   <source media="(min-width: 640px)" srcset="dest/640/tiger.jpg">
   <source srcset="dest/320/tiger.jpg">
   <img src="dest/640/tiger.jpg" alt="Imagem para navegadores sem suporte">
   <p>Texto para acessibilidade.</p>
</picture> 
Exemplo elemento picture

Uma imagem para cada tipo de tela

Para maiores informações veja o artigo Getting started with the Picture element.

Ferramentas de Otimização

Exportando imagens de editores como PhotoShop, FireWorks… ainda não é o suficiente para deixar sua imagem preparada para ser usada na web. Confira uma coleção de ferramentas para otimizar suas imagens.

  • http://kraken.io/
    Simplesmente a melhor ferramenta online de compactação de imagens. Ferramenta paga, porém há uma versão gratuita onde podemos enviar imagens de até 1MB.
  • http://compressor.io/
    Ferramenta totalmente gratuita, bem semelhante com a anterior.
Tabela comparativa

Exemplo de compactação

Font Icons

Caso você tenha que usar muitos ícones, considere usar Font Icons. Muitas vezes vale mais a pena fazer a requisição de uma fonte que usar imagens. Sem contar que esse tipo de ícone não perde qualidade ao ser redimensionado, já que fontes são vetores.