Eu <3 image bytes
Meu foco em JS e CSS foi motivado pelo desejo de baixar as imagens o mais breve possível. Mas usuários veem imagens. Eles não veem JS e CSS.
Muito do meu trabalho sobre desempenho web focou em JavaScript e CSS, começando pelas regras iniciais de Mova Scripts para o Fim e Coloque as folhas de estilo no início, lá atrás em 2007(!). Para enfatizar essas melhores práticas, eu costumava dizer que “JS e CSS são os bytes mais importantes em uma página”.
Alguns meses atrás, percebi que isso não era verdade. Imagens são os bytes mais importantes em uma página.
Meu foco em JS e CSS foi em boa parte motivado pelo desejo de realizar o download das imagens o mais breve possível. Usuários veem imagens. Eles não veem JS e CSS. É verdade que JS e CSS afetam o que é visto na página e mesmo se e como as imagens são exibidas (ex.: Carrossel JS de fotos, imagens CSS de background e media queries). Mas minha realização foi que JS e CSS são os meios pelos quais conseguimos essas imagens. Durante o carregamento da página, queremos o JS e o CSS fora do caminho o mais rápido possível para que as imagens (e textos) possam ser exibidos.
Minha principal motivação para otimizar JS e CSS é permitir que a renderização aconteça o mais rápido possível.
A renderização acontece com atraso
Com esse foco na renderização em mente, fui até o HTTP Archieve para ver qual a velocidade em que estamos renderizando as páginas. O HTTP Archieve roda sobre o WebPageTest, que, por sua vez, relata as seguintes medidas:
- time-to-first-byte (TTFB) – quando o primeiro pacote do documento HTML é recebido.
- start render – quando a página começa a renderizar.
- onload – quando o windows.onload é iniciado.
Eu extraí o 50º e 90º valores percentuais para essas medidas entre as 300 mil URLs mais acessadas no mundo. Como demonstrado, nada é renderizado até o primeiro terço do tempo de carregamento da página!
Tabela 1. Marcos de tempo durante o carregamento de página
| TTFB | início da rend. | onload | |
|---|---|---|---|
| 50% | 610 ms | 2227 ms | 6229 ms |
| 90% | 1780 ms | 5112 ms | 15969 ms |
Pré-carregamento
O fato de que a renderização não inicia até o primeiro 1/3 do tempo de carregamento total da página é de se espantar. Ao olhar para os dados das 50% e 90% das páginas do HTTP Archieve, vê-se que a renderização começa depois de aproximadamente 32-36% do tempo de carregamento. Leva-se 10% do tempo para conseguir o primeiro byte. Por isso, para aproximadamente 22-26% do tempo de carregamento, o navegador possui bytes para processar, mas nada é desenhado na tela. Durante esse tempo, o navegador normalmente está baixando e fazendo o parser de scripts e folhas de estilo – e ambos bloqueiam a renderização da página.
O navegador costumava ficar muito ocioso durante esta fase inicial do carregamento (depois do TTFB e antes do início da renderização). Isso porque quando um navegador antigo iniciava o download de um script, todos os outros downloads eram bloqueados. Isso ainda é visível no IE 6 e 7. Fabricantes de navegadores perceberam que apesar de ser verdade que ao construir a árvore DOM é preciso esperar que um script seja baixado e executado, não há razões para que outros recursos mais “profundos” da página não possam ser baixados em paralelo. A partir do IE 8, em 2009, navegadores começaram a ir além do script baixado no momento atual, a procurar por outros recursos (ex.: tags SCRIPT, IMG, LINK e IFRAME) e a carregar previamente essas requisições em paralelo. Um estudo mostrou que o pré-carregamento faz com que as páginas carreguem aproximadamente 20% mais rápido. Hoje, todos os principais navegadores suportam o pré-carregamento. Nestes resultados do Browserscope, são exibidas as versões mais recentes de cada um dos principais navegadores nos quais o pré-carregamento foi suportado pela primeira vez.
(À parte, creio que o pré-carregamento foi a melhoria que mais surtiu efeito no desempenho dos navegadores até agora. Imaginem hoje, com a abundância de scripts nas páginas da web, como seria o desempenho se cada script tivesse que ser baixado sequencialmente e bloqueasse todos os outros downloads.)
Pré-carregamento e imagens responsivas
Isso tem relação com este tweet de Jason Grigsby:
Serei sincero. Estou cansado de incentivar imagens responsivas e cada vez mais inclinado a encorajar os devs a usarem JS para simplesmente quebrarem o pré-carregamento.
As “imagens responsivas” às quais Jason se refere são técnicas em que as requisições de imagens são geradas pelo JavaScript. Isso é geralmente utilizado para adaptar o tamanho das imagens para diferentes tamanhos de telas. Um exemplo é o Picturefill. Quando você combina “pré-carregamento” com “imagens responsivas” surge uma questão – o pré-carregador olha à frente pelas tags IMG e encontra o SRC delas, mas técnicas de imagens responsivas normalmente não possuem um SRC, ou possuem uma imagem como um pixel 1×1 transparente. Isso anula os benefícios do pré-carregamento para as imagens. Portanto, há uma troca:
- Não usar imagens responsivas para que o pré-carregador possa começar a baixar imagens mais cedo, mas as imagens podem ser maiores do que o necessário para o seu dispositivo atual e por isso demorarem mais para serem baixadas (e custar mais para planos de dados limitados).
- Ou usar imagens responsivas que não tiram vantagem do pré-carregamento, o que significa que elas são carregadas depois que o JS necessário é baixado e executado, e os elementos DOM IMG foram criados.
Como diz Jason no tweet seguinte:
O que me deixa doido é que quase nada foi testado. Muita crença e poucos dados.
Não possuo nenhum dado comparando as perdas e os ganhos, mas os dados do HTTP Archieve mostrando que a renderização não começa até que 1/3 da página tenha sido carregada estão demonstrando isso. É provável que a renderização esteja sendo bloqueada por scripts, o que significa que o elemento IMG do DOM ainda não foi criado. Então, depois de algum ponto além do primeiro 1/3, as tags IMG são lidas e, em outro ponto além desse, a imagem JS responsiva é executada e inicia-se o download das imagens necessárias.
Na minha opinião, isso é muito tarde para iniciar as requisições pelas imagens, e provavelmente fará com que a renderização inicie mais tarde do que aconteceria caso o pré-carregador tivesse baixado as imagens. Novamente, eu não tenho dados comparando as duas técnicas. Além disso, não sei como o pré-carregador se comportaria com técnicas de imagens responsivas feitas através do markup (Jason escreveu um artigo que toca nesse assunto – The real conflict behind <picture> e @srcset).
O ideal seria ter uma solução de imagem responsiva no markup que funcionasse com os pré-carregadores. Até lá, fico nervoso de recomendar à comunidade de desenvolvedores que utilize imagens responsivas ao custo da perda do pré-carregamento. Espero que os navegadores acrescentem mais benefícios aos pré-carregadores e que os websites possam tirar vantagens desses benefícios tanto agora como no futuro.
***
Artigo traduzido pela Redação iMasters, com autorização do autor. Publicado originalmente em http://www.stevesouders.com/blog/2013/04/26/i/







