Pular para o conteúdo principal

Melhorando a performance em web sites

Segundo Patrick Chanezon (Google Developer Day 2009 - Criando aplicações Open Social rápidas e escaláveis) para o site da Amazon o retardo de 0,1 segundo no carregamento de uma página (latência) custa para eles 1% em vendas, e a redução do código do Google Maps para 30KB o fez crescer 30% em três semanas. Estes dados demonstram a importância adotar algumas precauções com o código desenvolvido nas aplicações que envolvem algum tipo de rede.

No processo de criação de um software agora fica a questão, criar uma aplicação voltada para ter muitos recursos ou obter maior velocidade?
Desenvolver uma aplicação com vários recursos resultara como conseqüência um código mais pesado gerando um retardo na velocidade. 

E desenvolver uma aplicação mais veloz poderá implicar em ter uma aplicação pobre em recursos. Ou seja, cada caso é um caso, a decisão depende da necessidade de cada evento.
Uma das dicas de leitura que Chanezon deixou foi o livro “Alta performance em web sites” de Steve Souders  um perito em performance em redes. Neste livro Souders descreve a importância da preocupação dos engenheiros de Front-end com o código desenvolvido, deixando 14 regras que poderão ser usadas para otimizar páginas web.

Em suas pesquisas no grupo de base de engenharia no Yahoo, descobriu que o browser gasta apenas de 10% a 20% de sue tempo para carregar o código HTML, os outros 80% restantes são gastos carregando outros componentes da página, e a esses componentes que se aplicam as seguintes regras:


Faça menos requisições HTTP

Como 80% do tempo gasto pelo browser são usados para carregar outros componentes reduzir as requisições HTTP é uma boa maneira diminuir o tempo de carregamento de uma página. Mas como realizar tal tarefa sem entrar em conflito com o design?
Existem varias maneiras, que podem ir de criar mapas de imagens, estampas CSS, imagens embutidas, até scripts e folhas de estilo combinados.


Use uma rede de distribuição de conteúdo

Ao crescer as empresas enfrentam o problema de contar com múltiplos servidores distribuídos em varias localidades. Usar um servidor para banco de dados outro para hospedar as páginas web, por exemplo, pode gerar algo como: aquele servidor que estiver mais próximo do cliente terá seus componentes baixados primeiramente.

A solução para o problema seria usar uma rede de distribuição de conteúdo. Uma rede de distribuição de conteúdo ou CDN (Content Delivery Network) é composta por uma série de servidores distribuídos geograficamente usados para distribuir o conteúdo de forma mais eficiente, a função da CDN é quando o cliente fizer uma requisição HTTP para um determinado servidor escolher aquele que apresenta um melhor tempo de resposta.

O lado bom para quem não tem sua própria CDN ou não pode pagar é que existem diversos desses serviços gratuitos na internet.


Adicione um cabeçalho expires

O protocolo HTTP funciona através de requisições e respostas, o browser faz uma determinada requisição HTTP GET que contém a URL da página solicitada seguida de cabeçalhos, e o servidor devolve uma resposta HTTP, contendo código de estados, cabeçalhos, mais o corpo da mensagem.

A função do cabeçalho expires é dizer ao cliente que ele pode armazenar determinado conteúdo no cache por um determinado período. Isto por que o browser usa o cache para diminuir o tempo de carregamento da página evitando requisições HTTP desnecessárias. Mas como o cabeçalho expires esta presente desde a versão HTTP/1.0 ele enfrenta um problema por que usa uma data fixa, que envolve a sincronização de relógios entre cliente e servidor.

Para solucionar esta limitação a versão do HTTP/1.1 trouxe o Cache-Control que usa a diretiva Max-Age que usa um determinado tempo em segundos, onde apenas o cliente é quem verifica se o tempo é menor que o estabelecido no cabeçalho para manter o conteúdo em cache.


Compacte seus scripts e folhas de estilo

Esta técnica é aplicada para compactar o código enviado ao cliente. Cuja função passou a estar disponível a partir da versão HTTP/1.1. O browser envia ao servidor um cabeçalho Accept-Encoding onde diz qual forma de compactação que suporta, e servidor compacta a resposta usando um dos métodos sugeridos pelo cliente, o notificando atravéz de um cabeçalho Content-Encoding.
Para reduzir o tamanho dos arquivos vale à pena compactar qualquer arquivo que envolva uma resposta em modo texto.


Coloque as suas folhas de estilo na seção head do documento usando a tag LINK

O browser baixa os componentes da página de forma progressiva, ou seja, à medida que aparecem no código. Usar folhas de estilo CSS no final da página evita a visualização progressiva em alguns browsers, por que ela acaba sendo bloqueada para evitar redesenhar conteúdos na página se o script mudar. O resultado é a tela branca enquanto a página carrega dando a impressão que esta parada.

As maneiras que as folhas de estilos são inseridas também influenciam na maneira que o browser ira interpreta.

Usar a tag link para inserir o código CSS tem se demonstrado mais eficaz do que usar a tag @import, porque em um bloco style (<style></style>) pode haver varias regras @import, e cada uma devem proceder à outra por ordem de carregamento, o mesmo não ocorre com a tag LINK.


Coloque os scripts no final da página

Arquivos JavaScript bloqueiam a visualização progressiva na página na parte posterior a inclusão do script, isto por que o browser baixa determinada quantidade de componentes em paralelo e os scripts devem seguir um determinada ordem para serem executados, então o browser aguarda o final do carregamento para verificar a ordem que ele será montado.
O motivo para inseri-los no final é que eles serão baixados após o carregamento da parte visual da página.


Evite expressões CSS

Expressões CSS são usadas para atribuir valores para propriedades CSS dinamicamente.
Ate este ponto tudo bem, funciona, mas o lado ruim de usar expressões é que elas são verificadas quando a pagina é carregada, redimensionada, rolada e ate mesmo quando o usuário movimenta o mouse sobre ela.

Para reduzir o problema existe alternativas, usar expressões de avaliação única, se uma expressão deve ser executada uma única vez ela pode sobrepor a si mesma como parte de sua execução.

Outra maneira é manipular os eventos manualmente para que sejam executados apenas nos eventos desejados evitando que sejam verificados a todo o momento.


Deixe o JavaScript e o CSS em arquivos externos

Teoricamente usar o código javascript e CSS embutidos na página junto com o código HTML torna mais rápido o carregamento que usá-los em arquivos externos por que o browser evita fazer mais requisições HTTP.

Mas na pratica ocorre o contrario, se o usuário visitar esta página mais de uma vez, por mês, por exemplo, sempre que ele requisitar a determinada página terá que carregar o código novamente. Isto por que documentos HTML que possuem conteúdo dinâmico são programados para não ser armazenado em cache pelo browser.

A vantagem de usar arquivos externos é que eles podem ser mantidos em cache no browser. Além disso, se outras páginas usarem o mesmo código, ele pode ser reaproveitado evitando a duplicação de código.

Mas sempre a exceções, há casos em que o cliente acessa essas páginas somente uma vez, páginas padrões e home pages. No caso da home Page um retardo ao carregar a página pode causar má impressão ao usuário que acessa o site pela primeira vez. Neste coso usar código embutido é melhor.


Reduza as pesquisas em DNS

A internet funciona através de endereços IPs, mas para tornar mais fácil a memorização dos endereços surgiram as URLs, é nessa parte que o DNS passa a ter função, ele traduz as URLs para endereços IPs.

O browser ao fazer requisições precisa que alguém traduza a URL para o endereço IP respectivo e para isto usa um servidor de DNS.

A desvantagem nesta tarefa é que até o browser fazer a requisição ao DNS encontrar determinada URL e devolve-la leva em média 20 a 120 milissegundos e nada pode ser baixado de um host enquanto transcorre a pesquisa.

Após ser traduzido este endereço IP permanece no cache do browser e do sistema operacional por um determinado período.

Quando o browser descartar este endereço do cache se ele ainda precisar pode pedir ao sistema operacional, mas se o mesmo houver descartado também deverá realizar ao DNS uma nova requisição.

Mas como os endereços IPs podem mudar frequentemente eles possuem um determinado tempo de vida (TTL, Time To Live) que diz ao browser por quanto tempo deve armazenar o endereço em cache. O ato de armazenar dados em cache consome recursos, por isso o browser ignora este período.


Minimize seus códigos fonte JavaScript

JavaScript é uma linguagem interpretada pelo cliente que oferece muitos benefícios. Mas se possuir um código muito extenso ira diminuir o tempo de resposta quando o browser baixar o arquivo. Para minimizar este problema existem técnicas como a minimização e o ofuscamento.

A técnica de ofuscamento é empregada para evitar a engenharia reversa, esta técnica remove e comentários, espaços em branco e substitui nomes de funções e variáveis. Ofuscar o código é uma técnica complexa que pode introduzir erros no código e dificultar a manutenção.

Já a técnica de minimização remove apenas caracteres desnecessários e espaços em banco, por isso é mais aconselhada. Ainda recomenda-se usar esta técnica aliada a compactação Gzip para aumentar a eficiência.


Evite Redirecionamentos 

Existem vários tipos de redirecionamento, mas os mais comuns são o 301 e 302. Quando o redirecionamento é envidado ao cliente ele possui um código na faixa 3xx, que indica ao browser o que deve fazer para que a requisição seja realizada.

Usar redirecionamento entre o cliente e a página HTML evita que o código HTML seja baixado enquanto o redirecionamento não é efetuado impedindo a visualização da página.

Um exemplo de redirecionamento que pode ocorrer sem a intenção do programador é esquecer-se de colocar o caractere barra (/) na final da URL quando o mesmo existe. Isto ocorre por que o cliente precisa informar um caminho ao enviar a requisição, como não encontra simplesmente poe a raiz de documentos.


Remova Scripts duplicados

Scripts duplicados afetam a performance da página por dois motivos podem induzir ao browser realizar requisições desnecessárias e o tempo de execução do código desperdiçado, por executar o mesmo script mais de uma vez.


Configure as Etags

ETags são usadas pelo clientes para verificar se os componentes que estão no cache são iguais aos que estão no servidor, algo parecido com a data mantida no cabeçalho expires.

As ETags foram criadas para serem únicas para cada componente. Isto por que elas se baseiam no tipo de servidor. Mas se no caso a página web estiver usando componentes hospedados em dois servidores já fica complicado por que as ETags não serão as mesmas para cada componente. Mesmo havendo um cabeçalho expires, esses dados não serão mantidos em cache por que as ETags prevalecem sobre os cabeçalhos expires resultando em um tempo de resposta maior devido as verificações que irão ocorrer toda vez que o cliente acessar a página. A solução para resolver este problema seria configurar as ETags ou simplesmente desativa-las.


Faça com que o Ajax se aproveite do cache

Ajax (Asynchronous Javascript and XML) como o nome já diz (Asynchronous = Instantâneo) o permite ao cliente ter respostas instantâneas de informações contidas no servidor. Mas dependendo do tipo de conexão com a internet que o cliente possui pode se tornar torturante para ter que esperar a resposta da requisição Ajax.

A técnica mais eficiente para amenizar o tempo de resposta é fazer com que as respostas sejam armazenadas em cache. Isto pode ser realizado usando algumas das regras anteriores como usar um cabeçalho expires.

Mas há casos onde o conteúdo de uma página poderá ser alterado frequentemente pelo usuário, a dica seria usar um identificador único para aquele usuário e aquela determinada ação.
Também a casos onde os dados não podem ser armazenados no cache por causa da privacidade, a alternativa é usar o protocolo SSl junto permitindo que os dados sejam validos apenas para a seção atual do browser.

Comentários