Melhorar o desempenho do site por meio de downloads paralelos de CSS?

15

Eu estava otimizando o tempo de carregamento da página de um site. Uma das maneiras era combinar várias solicitações HTTP para CSS em uma solicitação HTTP combinada. Mas um dos revisores fez uma pergunta interessante: paralelizar o download de vários arquivos CSS reduziria o tempo de carregamento da página?

Eu nunca considerei essa opção, pois a única coisa que li na internet é que reduzir o número de solicitações HTTP (bloqueadas) é essencial para uma página da Web mais rápida (embora o Google Pagespeed Insights não pareça indicar isso claramente 1 ).

Vejo algumas razões pelas quais a paralelização não melhoraria o desempenho ou importaria apenas muito pouco (superada pelo benefício de usar menos solicitações HTTP):

  • Configurar uma nova conexão é caro. Embora a configuração de várias conexões possa ser feita em paralelo, os navegadores usarão no máximo cerca de 4-6 conexões (dependendo do navegador); portanto, o download do CSS em paralelo impediria o download de outros ativos, como JavaScript e imagens.
  • A configuração de uma conexão HTTPS requer alguns dados extras. Eu li que isso pode ser facilmente alguns KBs de dados. Esses são alguns dados extras que precisam ser enviados por fio, em vez do CSS que realmente queremos enviar.
  • Devido ao algoritmo TCP Slow Start, quanto mais dados forem enviados por uma conexão, mais rápida será a conexão. Portanto, conexões com vida útil mais longa enviariam os dados muito mais rapidamente do que novas conexões. Veja, por exemplo, o protocolo SPDY, que usa uma única conexão para melhorar o tempo de carregamento da página.
  • O TCP é uma abstração: ainda existe (normalmente) apenas uma conexão subjacente. Portanto, enquanto várias solicitações são usadas, os dados enviados pela conexão podem não necessariamente se beneficiar de várias conexões para melhorar a velocidade.
  • As conexões com a Internet são inerentemente não confiáveis, especialmente em dispositivos móveis. Uma solicitação pode ser concluída significativamente mais rápido que a outra. O uso de várias solicitações de CSS significa que a renderização da página da web é bloqueada até que a última solicitação seja concluída, o que pode ser significativamente posterior à média da conexão.

Então, existe algum benefício em paralelizar solicitações HTTP para arquivos CSS?

Nota / atualização: todos os arquivos CSS são bloqueadores de renderização. Os arquivos CSS que ainda não foram movidos para fora do caminho crítico.

ayke
fonte
Eu vi algo no código de etsy como site de artesanato, onde eles recomendavam o uso de um único domínio sem cookies para objetos estáticos (css, imgs, js). Acontece que os navegadores modernos fazem um ótimo trabalho com downloads paralelos de um único domínio. Quanto a vários arquivos do mesmo domínio (10 arquivos css vs 1 grande), acho que é melhor combinar e minificar um arquivo grande e fazer apenas uma solicitação. Especialmente com CSS, onde seu site provavelmente precisará de todo o CSS para parecer correto.
Frank
De certa forma, os navegadores já fazem o download em paralelo, com base no número de conexões disponíveis para uso. É baseado no HTML que o navegador está lendo.
Sun

Respostas:

14

Os arquivos CSS vinculados a partir de documentos HTML são adicionados à fila de download paralelo à medida que o HTML é analisado; o principal é que os links JavaScript não assíncronos bloqueiem o analisador HTML, impedindo que tags posteriores sejam adicionadas à fila de downloads até que o JavaScript seja baixado, analisado e executado. [1]

Aqui está um exemplo que força o navegador a baixar três dos quatro arquivos sequencialmente (pelo menos três viagens de ida e volta):

<head>
  <script src="js/fizz.js"></script>
  <link rel="stylesheet" href="css/foo.css"/>
  <script src="js/buzz.js"></script>
  <link rel="stylesheet" href="css/bar.css"/>
</head>

Aqui está o exemplo reformulado para que todos os 4 arquivos sejam baixados em paralelo (pelo menos uma viagem de ida e volta):

<head>
  <link rel="stylesheet" href="css/foo.css"/>
  <link rel="stylesheet" href="css/bar.css"/>
  <script async src="js/fizz.js"></script>
  <script src="js/buzz.js"></script>
</head>

Outra observação: os arquivos CSS são (por padrão) bloqueio de renderização, não bloqueio de analisador; a página continuará sendo analisada e o DOM construído, mas a renderização não começará até que o CSSOM seja construído.

O principal motivo para dividir seu CSS é obter as regras mínimas necessárias para renderizar o conteúdo acima da dobra para o cliente e analisá-lo o mais rápido possível. O restante das regras, para itens que não são imediatamente visíveis, podem ser marcados como não necessariamente renderizados com as mediaconsultas na tag do link ou adicionados à página por JavaScript carregado de forma assíncrona.

Portanto, não há benefício claro em paralelizar seus downloads de CSS apenas por si. Mas como sempre, meça e teste!

Para uma leitura mais aprofundada, recomendo estes artigos sobre 'Fundamentos da web: otimizando o desempenho' do Google: https://developers.google.com/web/fundamentals/performance/

[1]: isso está ignorando o recurso de análise especulativa de alguns navegadores:

https://docs.google.com/document/d/1JQZXrONw1RrjrdD_Z9jq1ZKsHguh8UVGHY_MZgE63II/preview?hl=en-GB&forcehl=1

https://developer.mozilla.org/en-US/docs/Web/HTML/Optimizing_your_pages_for_speculative_parsing

Robert K. Bell
fonte
11
Outra boa leitura, sobre como manter seus scripts download ao mesmo tempo, é aqui: stackoverflow.com/questions/436411/...
joshreesjones
Vale ressaltar que todos os arquivos .js devem ser vinculados no final do código antes da tag de fechamento do corpo, para que não bloqueiem nada.
Chaoley
você pode elaborar "Então, não há nenhum benefício claro em paralelizar seus downloads de CSS apenas por si só"? De alguma forma eu não poderia descobrir isso a partir da resposta acima
gaurav5430
@ gaurav5430 Há não parece haver boas razões para dividir arquivos CSS, além de otimização para o acima da dobra tempo de render (e talvez otimização cache?)
Robert K. Sino