Performance Web

Diogo Cercílio

Porque otimizar o Front-end?

- Economiza recursos

- Geralmente a performance está relacionada ao front-end

- Sites rápidos tem uma melhor experiência para o usuário

- Existe uma relação direta entre performance e métricas de conversão (https://wpostats.com/)

Tá... Mas e aí?

Por onde eu posso começar?

- Automação com ferramentas

Um bom ponto de partida para a otimização é diminuir o número de bytes trafegados na rede.

- Remover comentários

- Remover Espaços em branco

Servidor e GZIP

- Habilitar GZIP

Servidor e GZIP

Servidor e GZIP

Servidor e GZIP

Dica: Brotli

https://opensource.googleblog.com/2015/09/introducing-brotli-new-compression.html
https://samsaffron.com/archive/2016/06/15/the-current-state-of-brotli-compression
https://blogs.akamai.com/2016/02/understanding-brotlis-potential.html

Uma alternativa ao GZIP que vem ganhando destaque nos últimos anos.

Otimização de imagens

- HTTP Arquive - http://httparchive.org/

- Tamanho das imagens

- Compressão (Lossless / Lossy)

                JPG - Ótima taxa de compressão. Largamente utilizada para imagens na web.
                PNG - Imagens transparentes
                GIF - Utilizado para animações, é um formato que vem perdendo popularidade.
                SVG - Imagens vetorizadas, baseadas em texto, com possibilidade de redimensionamento sem perda de qualidade. Muito utilizada para ícones.

- Tipos de Imagens

O custo dos Requests

Fast Overview - Chrome Devtools - Network (Controls, Filters, Overview, Request Table, Summary)

Request Table​

 Connections Setup

Queueing - Deixa um recurso menos prioritário na fila de espera.

Initial Connection - Quando inicia a conexão após as resoluções anteriores (Ex: DNS Lookup)

SSL - Resolução do certificado https

DNS lookup - Tempo que fica aguardando para a resolução do DNS

Stalled - Parado, aguardando para fazer o request (Ainda nem foi feito). Acontece porque as conexões do browser estão ocupadas

O custo dos Requests

  Request Reponse

Content Dowload - Quanto tempo demorou para baixar o conteudo

O custo dos Requests

Request Sent - Momento em que o Request em questão foi enviado

Waiting (TTFB) - Antes de começar a baixar (Tempo entre quando o navegador faz o request e a resposta chegar o primeiro byte). A alta latencia afeta muito isso.

Request Table​

Page Speed Insights

Web Page Test

Concatenação de Arquivos (CSS / JS)

- GZIP funciona melhor com arquivos concatenados

- grunt useref, grunt-concat

- reduz o travamento da rede (stalled)

Sprites

Inline de Recursos

Ajuda na renderização do Critical Path

Quais as vantagens?

Prioriza a renderização e (ou) execução de determinado recurso.

Inline de Recursos

Perda do Cachê do recurso

Quais as desvantagens?

Aumenta a complexidade do código

- Priorização do Above the fold.

Inline de Recursos

- Conceito de 1 RTT render.

Paralelização de Requests

Uma prática muito comum para aumentarmos o número de conexões simultâneas.

Com requests paralelizados podemos também trabalhar com domínios sem cookies, o que vai diminuir também o número de bytes trafegados.

Cache HTTP

- Expires no servidor.

Cache HTTP

- Visualização de arquivo vindo do cachê no Devtools:

Cache HTTP

- Fingerprint dos assets

Uma prática muito comum é deixar o cache com um valor alto, e fazer o controle desse arquivo cacheado por meio de mudanças na URL do arquivo. Por exemplo:

http://www.guichevirtual.com.br/public-1/css/main.css

http://www.guichevirtual.com.br/public-2/css/main.css

http://www.guichevirtual.com.br/public/css/main-123456.css

O controle da renomeação dos arquivo cacheados pode ser feito utilizando um automatizador de tarefas.

Performance é UX

A UX pode afetar diretamente a percepção do usuário em relação a vários fatores. E a performance é um deles.

Critical Path

Está relacionado a como vamos entregar o conteúdo da melhor maneira possível, por meio de otimizações de performance e também de melhorias na experiência do usuário.

O critical Path está relacionado ao primeiro momento do carregamento de uma página.

Critical Path

A ordem das coisas:

- O Browser lê os arquivos da esquerda pra direita, de cima pra baixo.

- O browser vai baixar em paralelo os arquivos blocantes, mas não vai continuar a execução até que esses arquivos blocantes terminem de ser baixados e executados

- Efetua os requests que for encontrando descrito no arquivo atual.

Critical Path

   A ordem das coisas:

Assíncrono

- Uso do async nos scripts (IE9+)

- Existem libs como o RequireJS com AMD, CommonJS, que fazem o carregamento assincrono do JS, mantendo a dependência

Existem algumas alternativas mais otimizadas para o setTimeout(), como por exemplo o "requestAnimationFrame()" e o "requestIdleCallback()".

Além de carregar os scripts de forma assincrona, também podemos adiar a execução dos scripts carregados conforme sua prioridade. Por exemplo:

// Será disparado depois de 3 segundos, deixando o critical rendering path ainda mais otimizado.

window.onload = function() { setTimeout(minhaFuncao, 3000) ;}

Assíncrono

Lazy Load

- Uso do Throttle

- Resources abaixo do "Above the fold"

- Atenção a possíveis  efeitos colaterais no SEO.

- Display none e o lazy load

Networking

- RRC (Radio Resource Control)

- Diferença Largura de banda X Latência

- RTT Round trip time

- Principais passos do request:
                - DNS lookup - 1RTT
                - TCP handshake - 1RTT
                - TLS handshake - 1-2 RTT
                - HTTP request - > 1RTT

- 3g quente e 3g frio (slow start)

- Atenção ao uso da Bateria do usuário.

- keep alive

HTTP 2

Lançado em 2015, o HTTP 2 é a mais recente versão do protocolo HTTP. Hoje milhares de projetos já o utilizam, devido aos enormes ganhos que o protocolo nos traz. Veremos aguns desses a seguir.

- No HTTP2 os headers vem Gzipado por padrão (com algoritmo chamado Hpack, específico para os headers)

- Gzip por padrão

- Uso de TLS por padrão (segurança trazido pelo Https), uma vez que atualmente apenas https aceita http2

HTTP 2

- Header Tables - Torna-se Stateful - Trabalha com o diff dos headers. Envia apenas as coisas que mudam na requisição, ou seja, não vai ficar mandando as informações que se repetem sempre (Ex: os cookies, user agent etc.). Com isso trafega menos bytes na rede

HTTP 2

Com tudo isso, torna-se muito menos necessário concatenar imagens, css, js etc, afim de reduzir o número de requests. Isso porque os requests serão feitos em uma única conexão TCP. Apesar disso, essas práticas precisam ser analisadas caso a caso, pois um número de request alto pode demandar um processamento maior do lado do servidor, trazendo perdas de performance mesmo com o HTTP 2

Com o multiplexing, não precisamos mais de várias conexões TCP, uma vez que o response é assincrono. Precisamos de apenas 1 conexão TCP. Isso economiza inclusive recursos do cliente, por exemplo bateria, no caso de usuário móvel.

Multiplexing

HTTP 2

Enxergando o Multiplexing na Prática

Enxergando o Multiplexing na Prática

HTTP 2

Enxergando o Multiplexing na Prática

HTTP 2

O browser não precisa mais abrir 6 conexões, mas sim 1.

Mais algumas observações sobre o HTTP2:

O http 2 se destaca muito em redes de alta latência (por exemplo mobile).

O HTTP 2 é compatível com os principais servidores e browsers. Caso o usuário acesse o site de um browser antigo que não suporte http2, o fallback é automatico.

HTTP 2

Server Push

Sempre que o browser faz a solicitação dos recursos, o servidor automaticamente atribui uma ordem de priorização para cada recurso retornado, baseado no que ele definiu ser mais importante (ex: jquery declarado no html antes de um plugin jquery que vai utiliza-lo. o servidor atribui uma importância maior para o que está vindo antes (jquery), pois entende que há uma dependência).

Antes de entender o server push, é necessário entendemos uma característica dos servidores (tanto no http1 quanto no 2):

No HTTP 2, o server push manda o response dos recursos antes mesmo deles terem sido requeridos. Veja abaixo:

Server Push

E abaixo um exemplo de uma visualização no Chrome com o resultado do server push:

Server Push

- É possível habilitar recursos no server push por meio de header no backend (ex: response.addHeader(...))

- É uma excelente alternativa ao uso do inline de recursos, com a grande vantagem de mantermos o cache dos recursos.

- O server push é cancelável, caso os recursos que o server esteja enviando já estejam em cache.

Link: <estilos.css>; rel=preload; as=style, <home.css>; rel=preload; as=style

Server Push

Resources Hints

Resource Hints são "dicas" que o o navegador envia para o servidor sobre ações futuras, relacionadas ao carregamento de recursos.

- DNS prefetch

O mais antigo dos resource hints. Veio antes mesmo do termo "resource hints". O navegador já vai resolvendo o DNS de um certo recurso antecipando que vamos precisar dele lá na frente. Para utiliza-lo basta adicionar o seguinte código no html:

<link rel="prefetch" href="//player.vimeo.com">
            <link rel="prefetch" href="//dependencia.player.vimeo.com"> etc...

Resources Hints

- PRE CONNECT

Faz o papel do DNS PREFETCH, porém além de incluir a resolução do DNS, também faz a conexão TCP, e se for uma conexão segura, também resolve a negociação SSL.     

Resources Hints

- PRE FETCH

 Antecipa o download de um determinado recurso que será usado no futuro, e o coloca no cache. É usado para navegações secundárias, e tem relevância menor a outros recursos. Ele é disparado apenas no momento em que os outros recursos forem finalizados. Ex de uso: Carregar recursos da página de rotas quando o usuário estiver na home.

Resources Hints

- PRELOAD

Igual ao PREFETCH, porém tem uma prioridade alta. Deve ser usado dentro da própria página, carregando recursos que serão disparados em um segundo momento (Ex: Imagem do Ônibus na página de busca). Caso tenhamos mais de um preload na página, podemos atribuir a prioridade deles usando o atributo 'as="style" as="script" as="image" as="font" ' etc. A ausência do "as" atribui prioridade baixissima.

Ainda falando das fontes, é possível passar um outro atributo chamado "type" (Ex:'type="font/woff2"'), que significa que só será feito o preload desse recurso caso o browser suporte o mesmo.

Um bom exemplo de aplicação do preload é usar para carregar custom fonts.

Resources Hints

- PRE RENDER

- Renderiza uma página completa em background

- Uma boa técnica de uso do pre-render é adicioná-lo ao dom pelo JS, dependendo de ações do usuário (Ex: Carregar a página de contato quando o usuário começar a preencher o e-mail)

Resources Hints

Performance e Budget

- Uma boa maneira de definir métricas do budget é se basear em site de concorrentes, e/ou com ferramentas que geram métricas globais (Ex: httparquive)

- http://www.performancebudget.io/
- Browser calories -chrome extension
- grunt-perfbudget
- WPO stats

Obrigado!

Links de referência

Performance na Web II - Alura

Performance na Web I - Alura

Blog Google Developers

www.alura.com.br/curso-online-otimizacao-performance-web

www.alura.com.br/curso-online-performance-http2-critical-path

developers.google.com/web/fundamentals/performance/rendering

WPO Stats

HTTP Arquive

Made with Slides.com