Olá a todos. Depois de perceber que existem dúvidas na forma de optimizar o tempo de resposta de um site, e porque te influência em termos de page rank e usabilidade decidi criar este post, que embora extenso, pode ajudar qualquer um a fazer melhorias e verificá-las posteriormente de uma forma fácil. Desculpem pelo tamanho mas julgo melhor desta forma.
Optimizar a página para caching
Muitas páginas Web incluem recursos que não mudam frequentemente, como por exemplo ficheiros CSS, imagens, Javascript, …
Estes recursos demoram tempo a ser descarregados através da rede, o que irá incrementar o tempo de carregamento da página. http caching permite que estes recursos sejam gravados ou fiquem na cache de um browser ou proxy. Se o recurso estiver na cache, o browser ou o proxy podem referir-se a esta cópia em cache em vez de descarregar os ficheiros de novo. Se isto não acontece em visitas sucessivas, então serão sempre descarregados em cada visita! Esta forma, permitir que os ficheiros fiquem em cache é uma jogada com vitória a dobrar: reduz o round-trip-time eliminando vários http requests (pedidos ao servidor), e reduz o tempo de resposta do servidor (Payload Time).
Browser caching
Definir uma data de expiração ou um máximo de idade no cabeçalho do http para recursos estáticos permite ao browser carregar previamente recursos anteriormente descarregados a partir de um disco local em vez de utilizar a rede para o fazer.
http suporta cache local de recursos estáticos pelo browser. Em todo o caso, a não ser que o servidor indique que determinado recurso poderá ficar em cache, o browser poderá assumir que o recurso não ficará em cache e repetir os pedidos sucessivos ao servidor por esses recursos em cada visita. Para tirarmos vantagem dos benefícios da cache, teremos de dar a instrução ao servidor para definir os headers http e aplicá-los a todos os recursos estáticos.
Os recursos que deverão ficar em cache são:
O HTML não é estático nem o deve ser, por isto não deve por si só ser considerado para ficar em cache.
HTTP/1.1 oferece-nos as seguintes respostas do cabeçalho:
- Expires e Cache-Control:Max-age – especificam o tempo de vida actualizado de um determinado recurso. O período de tempo enquanto este recurso poderá ficar em cache, sem a necessidade de validação se existe ou não uma nova versão no servidor. Importante é perceber que ao utilizar estes cabeçalhos, o browser nunca irá assumir um pedido GET ao servidor até que esta data se verifique ou que a idade máxima seja atingida.
- Last-Modified e eTag: especificam algumas características que o browser valida para determinar se os recursos são os mesmos.
O cabeçalho Last-modified é sempre uma data. O cabeçalho e-Tag pode ser um valor qualquer, desde que identifique univocamente o recurso em questão (versão do ficheiro ou hash-code são típicos para o e-tag). Last-modified é um cabeçalho fraco ao qual o browser aplica um método heurístico para determinar se coloca em cache ou não. Estes métodos heurísticos variam de browser para browser. Seja como for estes cabeçalhos permitem fazer pedidos GET condicionais (caso exista um refrescamento da página por exemplo) mas mesmo assim o servidor não devolve uma resposta completa se a versão no servidor for igual, o que reduz o tempo de latência relativamente a um pedido GET completo.
Assim, é importante especificar um dos dois: Expires ou Cache-Control: Max-age e ainda um dos dois: Last-modified ou e-Tag para todos os recursos estáticos. Importante e ainda realçar que é redundante a utilização simultânea de todos.
As minhas recomendações:
- Defina Expires como mínimo de um mês e até um ano. Prefiro expires a cache-control:Max-age porque é mais largamente aceite. Não o defina por mais de um ano pois viola as regras RFC. Caso saiba exactamente quando um recurso vai mudar, então defina uma data curta, se não souber defina uma data longa.
- Defina a data Last-modified para a data em que o recurso foi alterado pela última vez.
Proxy caching
Ao permitir publicamente que os seus recursos podem ficar em cache nos proxy's, significa que até novos visitantes poderão beneficiar do facto destes recursos estáticos estarem na cache de proxy's. Basta que já tenha sido efectuado um pedido através de um proxy que depois não voltará ao servidor para responder a pedidos idênticos. Dado que a lógica do proxy também é a proximidade, isto irá reduzir bastante o tempo de latência.
Utilize o cabeçalho Cache-Control:public para indicar que um determinado recurso poderá ficar em cache nos proxy's públicos, e nos browsers que façam o pedido. Com algumas excepções deverão configurar o servidor para que se tornem publicas as permissões de cache.
Excepções:
- Não inclua parâmetros (querystrings) nos URL's para recursos estáticos
- Não permita que recursos que utilizem cookies tenham permissões públicas de cache
Minimizar Round-trip Time (tempo de ida e volta: pedido e resposta)
O RTT é o tempo que demora para que um cliente envie um pedido ao servidor, e ainda o tempo que este demora a responder a esse mesmo pedido (sem incluir o tempo de transferência de dados). Isto é, inclui o tempo de back-end e preparação e exclui o tempo de transferência de dados entre cliente e servidor.
Por exemplo:
Um browser quer iniciar pela primeira vez uma conexão com o servidor. Devem ocorrer no mínimo 3 RTT's:
- RTT para DNS
- RTT para definir a conexão TCP
- RTT para o pedido http e para o primeiro byte da resposta.
É preciso perceber que muitas páginas necessitam de vários RTT's.
Desta forma é fundamental diminuir estes tempos para aumentar a performance. Como fazê-lo?
Minimizar DNS lookup
Reduzindo o número de servidores únicos a partir dos quais os recursos são acedidos corta o número de DNS resolution que o browser tem de fazer, e consequentemente os atrasos de RTT.
As minhas recomendações:
- Utilize URL's em vez de servidores sempre que possível. Por exemplo, é preferível colocar o site em www.dominio.pt/directorio ao invés de directorio.dominio.pt.
- Coloque os ficheiros Javascript no mesmo servidor. Desta forma evita-se o acesso a caminhos críticos (critical paths) que são os recursos necessários para o render da página. Ao reduzirmos estes caminhos críticos em termos de DNS resolution e ainda ao conseguirmos que o tempo de render do javascript aumenta, e assim, evita-se o efeito de bloqueio de recursos enquanto faz o render do javascript.
Minimizar redireccionamentos
Ao minimizarmos os redireccionamentos de um URL para outro estamos a eliminar RTT's adicionais e assim optimiza-se o tempo de espera dos utilizadores.
As minhas recomendações:
Combinar Javascript's externos
Combine vários Javascript's em apenas alguns ficheiros de forma a reduzir os RTT e atrasos ao descarregar os ficheiros. Não se esqueça que os ficheiros são descarregados sequencialmente.
As minhas recomendações:
- Crie dois ficheiros javascript: um com os dados para o render básico da página e outro com o restante código (sempre no mesmo servidor)
- Carregue os Javascript's apenas e quando necessário
- Para as pequenas partes de javascript que não devam ficar em cache, coloques directamente no código
- Tenha atenção à ordem com que os ficheiros são colocados no <head> pois será por essa ordem que serão carregados
Combinar CSS externos
Combine vários CSS's em apenas alguns ficheiros de forma a reduzir os RTT e atrasos ao descarregar os ficheiros.
As minhas recomendações:
- Crie dois ficheiros CSS: um com os dados para o render básico da página e outro com o restante código (sempre no mesmo servidor)
- Carregue os CSS's apenas e quando necessário
- Para as pequenas partes de CSS que não devam ficar em cache, coloques directamente no código
- Evite o uso da regra @import nos ficheiros CSS
- Tenha atenção à ordem com que os ficheiros são colocados no <head> pois será por essa ordem que serão carregados
Minimize o tamanho dos cookies
Manter os cookies o mais pequenos possível assegura que um pedido http poderá ser efectuado num único pacote de dados.
As minhas recomendações:
- Utilize a memória do servidor para a maior parte do tamanho de payload (apenas id é guardado no cookie)
- Remova os campos duplicados nos cookies
Sirva os recursos estáticos a partir de domínios sem cookies
Isto reduz o número de pedidos efectuados ao servidor para uma determinada página.
As minhas recomendações:
- Permita proxy-caching (public) – sem cookies não existe problema de cache
Teste aqui !!