Imagem post: Performance front-end – Parte 1
Browsers

Performance front-end – Parte 1

Entenda como você pode melhorar a velocidade do seu site de maneira rápida e simples.

Por
13

RTT (Road-trip Time) é o tempo que leva para o browser (ou qualquer outro cliente) conversar com o servidor buscando a informação solicitada pelo usuário.
Normalmente um browser inicia a comunicação com o servidor com pelo menos 3 RTTs: Uma requisição para a resolução do DNS. Outra para o setup de conexão TCP e outra para a requisição HTTP. Normalmente os websites tem muitas requisições HTTP. E isso é muito ruim. 

Ter muitas requisições significa que seu browser precisa ir e voltar várias vezes durante a abertura da página. Essa ida e volta são os RTT, ou a Road-trip Time. São as RTTs que contribuem para uma latência ruim nas redes. Se seu cliente demora para trazer a informação, o download da página é prejudicado.

Existem várias estratégias para que você diminua a quantidade de RTTs e melhore a performace da sua página sem fazer muito esforço. Com pequenos passos você consegue resultados bem grandes e interessantes. Lembre-se que alguma dicas não se aplicam a sites pequenos. Mas o que são sites pequenos? Sites pequenos são aqueles sites institucionais, os famosos “Home, Interna e Contato”. O site por si só já é minúsculo. A sua estrutura de arquivos é tranquila de se trabalhar e não precisa de tanta atenção. A performance desses sites dependem mais de onde o servidor está localizado, de qual CMS você estará utilizando e etc… Mas obviamente um mínimo de “asseio” é necessário.

Evite @import

Quando utilizamos um @import para adicionar diversos arquivos de CSS em apenas um, o browser precisa baixar o arquivo que importa o código, parsear e executar antes de descobrir que ele precisa baixar os arquivos importados.

Recomenda-se utilizar a tag link para importar os arquivos separadamente ou utilizar qualquer script que junte os arquivos e minimize para que todo seu código CSS se transforme em apenas um. Dependendo da linguagem utilizada, isso pode ser feito automaticamente, como em projetos Ruby on Rails.

Otimize a ordem dos seus scripts e estilos

Colocar a chamada dos arquivos na ordem correta pode ajudar bastante no carregamento da página. Códigos Javascripts geralmente modificam e alteram o conteúdo da página, logo os browsers demoram mais para rederizá-los por que é necessário que todas as funções daquele scripts sejam executadas e somente depois ele começa o download de outro arquivo.

Imagine que você tenha 3 arquivos de CSS e 2 de JS para chamar na sua página, e você o faz assim:

<link rel="stylesheet" type="text/css" href="stylesheet1.css">
<script type="text/javascript" src="scriptfile1.js">
<script type="text/javascript" src="scriptfile2.js">
<link rel="stylesheet" type="text/css" href="stylesheet2.css">
<link rel="stylesheet" type="text/css" href="stylesheet3.css">

Suponha agora que para fazer o download de cada um desses arquivos demora em torno de 100ms (milisegundos), o download dos arquivos seria algo como a imagem abaixo. Essa imagem peguei de uma página do Google que fala sobre o mesmo assunto:

Se você simplesmente ordenar os arquivos de outra forma, o carregamento pode ficar apenas em 200ms. Ok, você deve estar falando que eu sou louco por me preocupar com milisegundos… Mas milisegundos podem se transformar em segundos quando nós nos preocupamos.

<link rel="stylesheet" type="text/css" href="stylesheet1.css">
<link rel="stylesheet" type="text/css" href="stylesheet2.css">
<link rel="stylesheet" type="text/css" href="stylesheet3.css">
<script type="text/javascript" src="scriptfile1.js">
<script type="text/javascript" src="scriptfile2.js">

O browser baixa paralelamente os três arquivos de CSS e o primeiro arquivo de JS. Depois que o primeiro arquivo de JS foi baixado, ele começa a baixar o segundo. É uma boa prática colocar os arquivos de CSS baixarem primeiro, uma por que a renderização do browser é mais rápida quando se trata de código CSS e outra que o JS pode modificar características desses CSS, logo eles precisar estar carregados quando os scripts forem funcionar.

Combine imagens utilizando sprites

Tivemos um artigo muito bom aqui no Tableless mostrando como funcionam os CSS Sprites. É uma técnica antiga, utilizada durante muito tempo em consoles com baixa memória para guardar grandes quantidades de imagens e informações.

Sempre utilize CSS Sprites onde puder. Se você tem uma grande quantidade de ícones, se você tem uma grande quantidade de imagens decorativas e etc… Junte-as e forme um sprite de imagens que possa ser utilizado por todo o site. Isso diminui a quantidade de requisições que o browser fará no decorrer da navegação do usuário.

Quando utilizamos muitas imagens pequenas e o browser precisa fazer essas requisições juntas, há um acumulo de tarefas, chama-se request overhead.

Eu sei que trabalhar com sprites dá trabalho para manter e principalmente criar o sprite inicial. Por isso dá para usar serviços para fazer esse trabalho para você. O SpriteMe é um deles.

Combine arquivos de CSS

Modular CSS é uma coisa boa, mas é bom para sua organização. Quando nós separamos nosso código CSS em vários arquivos, isso significa que o browser vai ter que buscar cada um desses arquivos no servidor. Logo, se você modula seu CSS, você precisa fazer um trabalho de entrega desse código apenas quando for necessário. Por exemplo: se você separa o estilo da página de contato em um arquivo contato.css, o mais inteligente seria chamá-lo apenas na página de contato e assim por diante para as outras páginas.
Se você simplesmente modula seu CSS em vários arquivos, mas não faz esse planejamento de distribuição, a modularização de CSS só servirá para sua organização pessoal.

Quando combinamos os códigos CSS em um só, diminuimos a latência. O Google recomenda que tenha no máximo 3 arquivos linkados, mas o perfeito seriam 2 arquivos. Em projetos utilizando Ruby on Rails, por exemplo, é possível juntar automaticamente todo os arquivos em apenas um, sem trabalho manual. Ele ainda minimiza seu código arrancando espaços, quebras de linha e etc. Logo você precisa chamar apenas um arquivo. Baixar um arquivo grande é muito melhor do que baixar vários pequenininhos. Por quê? Requisições, lembra?

Combine arquivos de Javascript

Pelo mesmo motivo de combinar arquivos de CSS. Dá uma olhada nessa imagem que o Google disponibilizou:

Carregamento de arquivos separados

Quando linkamos uma série de arquivos separadamente, produzimos uma série de requisições no servidor e isso é ruim. Lembre-se que o sinal tem que ir e voltar para podermos começar a carregar os arquivos. Por isso é melhor você carregar um arquivo grande do que vários pequenos. A quantidade de requisições diminui e por isso tempo de carregamento é menor. Veja a imagem abaixo:

Carregamento de um arquivo

Bem diferente, né?

Você pode modularizar seus arquivos de forma que você melhore o carregamento e ainda não prejudique seu site. Por exemplo, você pode separar em um arquivo o mínimo de código que será necessário carregar para que a página funcione e em outro arquivo vai todo código que pode ser carregado depois que a página terminar de abrir. Assim você divide as prioridades.

Se for pouco Javascript, algo bem básico mesmo, considere colocá-lo direto no HTML. Sem a necessidade de chamar um arquivo.

Tente paralelizar downloads de vários domínios

De acordo com o protocolo de HTTP, os browsers podem pode ter duas conexões simultâneas por domínio. Se um documento contem referencias para várias recursos como CSS, Javascripts, Imagens e etc, de forma que estoure o máximo permitido pelo host, o browser começa a baixar um parte e deixa os outros recursos na fila. Quando ele termina de baixar todos os recursos atuais, ele vai pra fila e pega o próximo grupo.

O problema é que a cada grupo que o browser baixa, é gerado um RTT. Ou seja, se você tem 100 arquivos para baixar (CSS, Javascripts, imagens etc), levando em conta que o browser baixa 4 recursos por vez, serão 25 RTTs gerados.

A estratégia é separar parte destes recursos em outro domínio. Fazendo isso o browser pode baixar o máximo de recursos por domínio paralelamente. Por isso é que normalmente separamos arquivos – como imagens – em outro servidor.

Veja no Browserscope a lista dos browsers que aceitam ou não fazer esse truque. Normalmente os browsers mais novos estão tranquilos.

Outras dicas

Algumas outras dicas e recomendações podem ser vistas neste documento que o Google disponibilizou sobre boas práticas sobre como deixar sites mais rápidos.

Veja a segunda parte deste artigo aqui.

13

Por Diego Eis

Diego Eis criou o Tableless para disseminar os padrões web no Brasil. Como consultor já treinou equipes de empresas como Nokia, Globo.com, Yahoo! e iG. É palestrante e empreendedor.

http://about.me/diegoeis/

Mais posts do autor

  • http://www.facebook.com/samuelmesq Samuel Mesquita

    Ótima diga, e muito importante. já tem um tempo que aprendi essa dicas e melhoraram em muito o carregamento das páginas.

  • Lol

    usar o ip ao invés do dominio evitaria a parte da resolução TCP certo? ou estou enganado?

  • http://twitter.com/tableless Tableless

    O problema é quando são vários servidores, vários lugares para puxar os assets e etc. Aí isso fica impraticável.

  • http://twitter.com/lhvolso Luiz Henrique Volso

    Diego, você fala do @import do CSS, como fica o INCLUDE do PHP? Existe também essa requisição extra?

  • Frederico Wuerges Becker

    Pra sanar esse problema de modularização e diferentes arquivos de css (isso se encaixa pra JS também), pensei em implementar uma funcionalidade pra juntar esses arquivos em tempo de execução (via PHP).
    Mas estudando mais a fundo, esbarrei na questão de performance na parte de servidor, pois causaria lentidão em ambientes que tenham muitos acessos, pelo fato de haver muita escrita/leitura de arquivos no servidor.
    Aí entra a questão de caching desses arquivos agrupados, assim evitando essa lentidão de escrita/leitura no servidor.

  • http://twitter.com/MarioDavi Mário Davi

    Como otimizar a ordem dos scripts e estilos quando estes são inseridos pelos plugins do wordpress?! Como organizar essa serialização?!

  • Rodrigo DK

    Bom o artigo na parte didatica e tal, mas o RTT refere-se ao ROUND trip time ou melhor ao round trip delay time, ou “tempo de atraso de viagem de ida e volta” em tradução livre, e não ao road trip time, que sequer existe na literatura cientifica da área.

    Mas o principal culpado é o tempo de parsing e interpretação do navegador, já que ele evita paralelizar o download dos scripts por não haver garantias na ordem de depedencias.

    Já a parte da resolução DNS o nosso S.O. faz cache de tudo, de maneira limitada, mas suficiente para descartar idéias malucas como colocar o ip no lugar do nome. Mas o ideal ainda continua sendo usar diretórios relativos, e não subdominios para guardar assets e tal. Como utilizar subdominios (normalmente em conjunto com CDNs) é uma solução mais prática para todos, e espera-se que o cache do S.O. funcione para os acessos subsequentes, então adota-se subdominios com consequencias desprezíveis.

    O que realmente é importante no tempo de resposta, no caso do parsing de javascript é de fato a unificação dos arquivos, já que aí você unifica do jeito que funcionar (temos que lembrar das garantias das dependencias, que deixam de ser responsabilidade do navegador e sim do programador) fazendo como que o browser utilize toda tua largura de banda de uma vez só, sem precisar interpretar um por um antes de requisitar o próximo.

    No entanto usar javascripts REALMENTE famosos de CDNs acessados a todo momento (por exemplo os JS hospedados pelo google), por vários sites, na verdade traz uma economia, já que o navegador pode acessar da sua cache. O tradeoff seria o tempo de resposta de ambos (do teu site e do CDN do JS), que seria balizado pelo pior deles, caso não estivesse em cache.

    Outro dia ocorreu isso comigo pois meu provedor estava muito lento somente para o Google Ads, e todos os blogs e sites que o usavam ficaram com um grande atraso no tempo de carregamento total.

    Sobre os sprites, só vale a pena fazer realmente se você ultrapassar o limite do paralelismo dos navegadores, que testando aqui no meu firebug é de 10 itens simultaneos. So número for bem maior do que isso ( quando por exemplo, você utiliza muitos marcadores e ícones diferentes) aí vale a pena. Com poucos itens é muito tempo.

    Mas o que temos que ter em mente de verdade é sobre a quantidade de “penduricalhos” no nosso site, como os comentários aqui do disqus, mais não sei o que do facebook, mais não sei o que do google+. Internalizar esses assets é o melhor, e evitar o javascript deles, principalmente carregamento externo é o melhor (muito programador simplesmente copia e cola de tutoriais e seções de ajuda desses serviços sem pensar nos custos, inclusive em portais de bom porte, como clicRBS (famoso aqui no Sul). Lembre-se que o navegador pode atrasar o tempo de painting balizado pelo pior tempo de resposta dentre todos esses penduricalhos colocados.

  • Leandro Correa dos Santos

    O include do PHP não representa um problema. Todo código PHP é compilado e retorna em forma de HTML para o servidor, que enviará o código ao navegador, portanto, não gera requisição extra.

  • http://waister.me/ Waister Nunes

    Você gerar um arquivo físico com o resultado da concatenação (“cache.css”, por exemplo). Depois é só verificar as datas dos arquivos para saber se é preciso gerar um novo ”cache.css”…

  • Paulo Henrique Tavares

    Recomendo usar Cloudflare (CDN), e para avaliar a se a otimização boa o Google Page Speed, que ta uma nota e também dicas para melhorar resquisições, cache, imagens, etc.

    No WordPress uso o W3 Total Cache, e compacto todo CSS e JavaScript de todos plugins em um só.

    Tenho usado e faz uma baita diferença, coisa de até 50% mais rápido.

  • Igor

    O post parece quebrado na versão móvel. acessando de um galaxy note, e o site se adaptou legal na inteface mas o post só vai até determinada parte e não continua…

    A parte até onde vai e [cc lang=html]

  • http://tableless.com.br Tableless

    Arrumado Igor. valeu!

  • http://tableless.com.br Tableless

    Aí o bicho pega.
    O certo é avaliar o plugin antes de usar, mas as vezes, os plugins que são padrão no mercado fazem o lixo. Nesse caso não tem jeito. É tentar fazer eles serem carregados nos lugares corretos e verificar se o plugin tem alguma saída para customizar o carregamento dos scripts.

Mais artigos