1, 2, 3... LIVE!
Performance no frontend:
faça suas aplicações voarem
Slide 2
Slide 2 text
Carlos Antonio
@cantoniodasilva
Slide 3
Slide 3 text
@plataformatec
Slide 4
Slide 4 text
Desenvolvemos
aplicações em Rails
@plataformatec
Slide 5
Slide 5 text
Desenvolvemos
aplicações em Rails
Coaching em
Rails e Agile
@plataformatec
Slide 6
Slide 6 text
Desenvolvemos
aplicações em Rails
Consultoria
Coaching em
Rails e Agile
@plataformatec
Slide 7
Slide 7 text
Novo projeto => Yay!
Slide 8
Slide 8 text
X meses depois...
Slide 9
Slide 9 text
DONE!
Slide 10
Slide 10 text
Hora do deploy \o/
Slide 11
Slide 11 text
Setup do servidor - ruby,
rubygems, etc...
Setup do apache ou nginx
Passenger
Capistrano
...
Slide 12
Slide 12 text
cap production deploy...
Sucesso!
Slide 13
Slide 13 text
Hora das férias?
Slide 14
Slide 14 text
yeah!
Slide 15
Slide 15 text
No 1º (feliz) dia de férias:
O cliente liga: a app está
morrendo, lenta, demora uma
vida para carregar!
Slide 16
Slide 16 text
1 vida == 10s
Slide 17
Slide 17 text
:bomb:
Slide 18
Slide 18 text
Esperar é um saco.
Slide 19
Slide 19 text
E a culpa é de quem?
Slide 20
Slide 20 text
Ruby é lento.
Slide 21
Slide 21 text
Será mesmo?
Slide 22
Slide 22 text
80 a 90% do tempo de
renderização é gasto no
navegador.
Slide 23
Slide 23 text
WTF!?!
Slide 24
Slide 24 text
SIM!
A maior parte do tempo de
renderização de uma página não é
gasto no servidor, mas sim no
navegador.
Slide 25
Slide 25 text
Performance?
Vamos otimizar o frontend!
Slide 26
Slide 26 text
Hora do checklist!
Slide 27
Slide 27 text
#1 Diminuir o número de requisições
#2 Utilizar um CDN
#3 Evitar src ou href vazios
#4 Adicionar header Expires
#5 Habilitar Gzip
#6 Colocar CSS no topo
#7 Colocar JS no final
#8 Evitar expressões CSS
#9 Deixar JS e CSS em arquivos externos
#10 Reduzir Lookups DNS
#11 Minificar JS e CSS
#12 Evitar redirects
#13 Remover scripts duplicados
#14 Configurar ETags
#15 Permitir cache para Ajax
#16 Usar GET para requisições Ajax
#17 Reduzir o número de elementos DOM
#18 Evitar 404
#19 Reduzir o tamanho dos cookies
#20 Usar domínios sem cookie para componentes
#21 Evitar filtros
#22 Não escalar imagens no HTML
#23 Ter um favicon.ico pequeno e cacheável
Slide 28
Slide 28 text
Ahhhhhhhhhhh!
Tudo isso?
Slide 29
Slide 29 text
Easy!
Slide 30
Slide 30 text
#1 Diminuir o número de requisições
Combine arquivos
JS CSS
Slide 31
Slide 31 text
#1 Diminuir o número de requisições
Sirva 1 arquivo js e 1
arquivo css em produção.
Arquivos separados
ajudam a organizar em
desenvolvimento. Mas o
usuário não precisa disso.
Jammit, Asset Packager, Rails 3.1 asset pipeline, etc.
Slide 32
Slide 32 text
#1 Diminuir o número de requisições
Slide 33
Slide 33 text
#1 Diminuir o número de requisições
Use CSS Sprites
Combine imagens pequenas
em uma única imagem maior.
Slide 34
Slide 34 text
#2 Utilizar um CDN
Distribua seus assets em
diferentes lugares, mais
próximos do usuário.
Akamai Technologies, EdgeCast, level3
Slide 35
Slide 35 text
#2 Utilizar um CDN
Para aplicações realmente
grandes! $$
Slide 36
Slide 36 text
#3 Evitar src ou href vazios
Browsers constumam fazer
uma nova requisição para a
página atual.
Isso está definido em RFC, então em teoria
os browsers estão fazendo o correto.
Browsers novos ignoram isso.
HTML 5 adicionou na RFC instrução para
ignorar src/href vazios.
Slide 37
Slide 37 text
#3 Evitar src ou href vazios
E não precisamos de
requisições que não valem nada.
Slide 38
Slide 38 text
#4 Adicionar header Expires
Diga para seu navegador
fazer cache de assets por
algum tempo.
Slide 39
Slide 39 text
#4 Adicionar header Expires
Mas não eternamente!
1 mês ~ 1 ano
Slide 40
Slide 40 text
#4 Adicionar header Expires
Apache => mod_expires
ExpiresActive On
ExpiresDefault "access plus 1 month"
#6 Colocar CSS no topo
CSS é carregado e
interpretado mais rápido.
Mais feedback visual
para o usuário!
Example App
Slide 48
Slide 48 text
#7 Colocar JS no final
Scripts bloqueiam
downloads paralelos e
renderização da página.
Slide 49
Slide 49 text
#8 Evitar expressões CSS
Expressões são executadas a
cada render, resize, scroll, ou
movimento do mouse!
background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );
Slide 50
Slide 50 text
#9 Deixar JS e CSS em arquivos externos
Arquivos externos podem
ser cacheados.
Js/css inline, não.
Remover do html
também diminui o
tamanho final da página.
Slide 51
Slide 51 text
#10 Reduzir Lookups DNS
Muitos hosts diferentes que
não estão cacheados,
significam mais tempo para
lookup de DNS.
Navegadores possuem
cache de DNS, e cada
navegador expira isso em
um tempo diferente.
100~120 ms por lookup
de DNS
Slide 52
Slide 52 text
#10 Reduzir Lookups DNS
3 Lookups de DNS
foo.com/image1.png
bar.com/image2.png
baz.com/image3.png
Slide 53
Slide 53 text
#11 Minificar JS e CSS
Elimine tudo que não é
necessário dos arquivos:
espaços, comentários, etc.
Diferença entre
minificar e obfuscar?
Slide 54
Slide 54 text
#11 Minificar JS e CSS
20 ~ 25% de ganho no
tamanho dos arquivos.
Slide 55
Slide 55 text
#11 Minificar JS e CSS
Mas não faça isso manualmente!
Existem diversas ferramentas
para ajudar nesse processo.
Closure Compiler, YUI Compressor, UglifyJS, Packer, JSMin, CSSMin, etc...
Slide 56
Slide 56 text
#12 Evitar redirects
HTTP status 301 e 302 são
extremamente custosos, e
fazem o usuário esperar mais.
Slide 57
Slide 57 text
#13 Remover scripts duplicados
Duplo trabalho? Quem gosta.
É mais comum do que
imaginamos.
Um estudo do Yahoo
mostrou que 2 dos 10
sites mais acessados dos
EUA possuía scripts
duplicados.
#14 Configurar ETags
Padrão Otimizado
304 Not modifed
200 OK
Requisição 1
Requisição 2
200 OK
Requisição 1
Requisição 2 +
ETag em cache
200 OK + ETag
Servidor envia header ETag junto com o componente requisitado.
Navegador requisita o componente novamente, enviando ETag em cache.
Servidor retorna 304 se a ETag do componente não mudou.
If-None-Match
Slide 60
Slide 60 text
#15 Permitir cache para Ajax
Assíncrono != Instântaneo
Tenha os mesmos cuidados com
cache em requisições Ajax.
Slide 61
Slide 61 text
#16 Usar GET para requisições Ajax
POST usa 2 etapas: 1 para enviar os
cabeçalhos, outro para enviar o body.
Não quer dizer que não é
para usar POST. Quer
dizer: não use POST por
usar.
Slide 62
Slide 62 text
#17 Reduzir o número de elementos DOM
Muitos elementos significam uma
página complexa de renderizar, e mais
lenta para acessar usando javascript.
document.getElementsByTagName('*').length
Slide 63
Slide 63 text
#17 Reduzir o número de elementos DOM
Cuidado com
para montar seu layout!
Slide 64
Slide 64 text
#18 Evitar 404
Fazer uma requisição para receber
404 é jogar tempo fora.
Isso é muito comum com assets!
Slide 65
Slide 65 text
#19 Reduzir o tamanho dos cookies
Cookies são enviados em TODOS os
requests, inclusive para assets.
Quanto menor o tamanho dos
cookies, melhor!
Slide 66
Slide 66 text
#20 Usar domínios sem cookie para componentes
Assets não precisam de cookies. Eles
são tráfego de rede desnecessário.
Slide 67
Slide 67 text
#20 Usar domínios sem cookie para componentes
Site => www.example.org
(www seta cookies)
Assets => static.example.org
(cookie-free)
Slide 68
Slide 68 text
#20 Usar domínios sem cookie para componentes
Site => example.org
(seta cookies)
Assets => static.example.org
(seta cookies - já era)
Use outro host diferente
static-example.org
Slide 69
Slide 69 text
#21 Evitar filtros
AlphaImageLoader para corrigir
transparência do IE < 7.
Esqueça!
Slide 70
Slide 70 text
#22 Não escalar imagens no HTML
Imagem maior == download maior.
Escalar no navegador == mais
processamento para renderizar.
Slide 71
Slide 71 text
#23 Ter um favicon.ico pequeno e cacheável
É um mal necessário, então é melhor
não responder com 404.
Slide 72
Slide 72 text
#23 Ter um favicon.ico pequeno e cacheável
Mantenha pequeno, abaixo de 1kb.
Define um header Expires para alguns
meses no futuro.
Não coloque muito tempo
de Expires, pois o seu
nome não pode ser
mudado para expirar o
cache.