Web Performance

Por que seu site deve enviar menos requisições, não apenas requisições menores

Arquivos minúsculos não são gratuitos. O HTTP moderno reduziu a sobrecarga das requisições, mas não a tornou irrelevante.

The Wux Webtools Team The Wux Webtools Team 11 min de leitura Assistido por IA, revisado por humanos
A stylized browser waterfall showing many small requests simplified into fewer intentional requests.
Tabela de conteúdos
  1. O mito confortável de “basta deixar todos os arquivos menores”
  2. Requisições não são apenas bytes
  3. “Mas o HTTP/2 resolveu isso”, em grande parte não
  4. A cascata é onde a verdade está
  5. Arquivos menores ainda importam — só não igualmente
  6. Os custos ocultos de muitos arquivos pequenos
  7. 1. Descoberta tardia
  8. 2. Sobrecarga de headers
  9. 3. Interrupção da thread principal
  10. 4. Complexidade de cache
  11. Bundling voltou, mas com critério
  12. Requisições de terceiros merecem desconfiança extra
  13. Um checklist prático para reduzir requisições
  14. Remover
  15. Combinar com cuidado
  16. Adiar
  17. Cachear corretamente
  18. Medir novamente
  19. Como é um bom resultado

O mito confortável de “basta deixar todos os arquivos menores”

Durante anos, os conselhos de performance web pareciam simples: comprima tudo, minifique tudo, deixe todos os assets menores.

Esse conselho ainda é amplamente correto. Um script de 40 KB costuma ser melhor que um script de 400 KB. Uma imagem otimizada é melhor que uma exportação bruta. Brotli, AVIF, minificação de CSS, tree shaking e subsetting de fontes importam.

Mas, em muitos sites de produção, o problema maior já não é um único arquivo grande demais. É a quantidade de coisas que o navegador precisa pedir antes que a página pareça utilizável.

Uma página pode parecer disciplinada em tamanho de arquivos e ainda assim ser lenta porque envia 120 requisições: fragmentos de CSS, chunks de JavaScript, tags de terceiros, arquivos de fonte, pixels de rastreamento, sprites de ícones, endpoints JSON, preloads, beacons de analytics e revalidações de cache. Cada uma pode ser “pequena”. Juntas, elas criam uma cascata longa e frágil.

A regra prática é esta: depois que os assets individuais estão razoavelmente comprimidos, reduzir o número de requisições muitas vezes melhora mais a experiência do usuário do que cortar alguns kilobytes de cada arquivo.

Requisições não são apenas bytes

Uma requisição de rede não é apenas uma transferência de dados. É uma sequência de trabalho.

O navegador precisa descobrir o recurso, decidir quando buscá-lo, agendá-lo em relação a outros recursos, enviar headers, esperar pelo servidor, receber headers, analisar a resposta, muitas vezes descomprimi-la e então fazer algo útil com ela.

Esse “algo útil” pode ser caro. Um arquivo JavaScript precisa ser analisado, compilado e executado. Um arquivo CSS pode bloquear a renderização. Um arquivo de fonte pode atrasar o texto legível ou causar mudanças de layout. Uma imagem pode afetar o elemento de Largest Contentful Paint. Um script de terceiro pode trazer sua própria cadeia de dependências.

É por isso que a contagem de requisições ainda importa mesmo quando os arquivos são pequenos. Um script de 3 KB pode ser pior que uma imagem de 30 KB se bloquear a renderização, chegar tarde e executar na thread principal no momento errado.

Se você está lendo um relatório do Lighthouse e se sente punido por dezenas de alertas separados, comece olhando para a cascata de requisições em vez de pontuações individuais. Temos um passo a passo prático em como ler um relatório do Lighthouse sem entrar em pânico, mas a versão curta é: encontre o que bloqueia a primeira renderização e o que atrasa o conteúdo principal.

“Mas o HTTP/2 resolveu isso”, em grande parte não

HTTP/2 e HTTP/3 mudaram a economia das requisições. Eles introduziram multiplexação, compressão de headers e melhor comportamento de conexão. Em termos simples, os navegadores ficaram muito melhores em enviar múltiplas requisições por menos conexões.

Isso foi uma melhoria real. Também eliminou alguns hábitos antigos, como sprites CSS extremos e bundles gigantes concatenados criados apenas para evitar limites de conexão.

Mas o HTTP/2 não tornou as requisições gratuitas.

A multiplexação ajuda quando muitos recursos compartilham uma conexão, mas o navegador ainda precisa priorizá-los. Os servidores ainda precisam responder. O cliente ainda precisa processar cada resposta. Congestionamento, perda de pacotes, negociação TLS, lookup de DNS, cache misses e pressão na thread principal ainda existem.

O HTTP/3 melhora alguns comportamentos de transporte, especialmente em relação à migração de conexão e ao head-of-line blocking na camada de transporte. Ele não remove o custo de descobrir, agendar, baixar, analisar e executar recursos.

Portanto, o objetivo moderno não é “empacotar tudo em um arquivo enorme”. É “enviar menos requisições críticas e tornar as requisições restantes intencionais”.

A cascata é onde a verdade está

Problemas de performance raramente se anunciam em uma única métrica. Eles aparecem como forma.

Abra o painel de rede do navegador e observe os primeiros segundos. Pergunte:

  • Quantas requisições começam antes que o conteúdo principal apareça?
  • Quais requisições bloqueiam a renderização?
  • Recursos importantes são descobertos tarde?
  • Scripts de terceiros estão competindo com CSS, fontes ou imagens de primeira parte?
  • Muitos arquivos estão retornando respostas 304 em vez de serem servidos diretamente do cache?
  • Ícones, fontes ou fragmentos de UI estão divididos em mais arquivos do que a página precisa?

Uma página rápida normalmente tem uma cascata inicial sem drama. Um pequeno número de recursos críticos chega cedo. Recursos não críticos aguardam. Scripts de terceiros são adiados, limitados ou removidos. O navegador não é forçado a equilibrar vinte prioridades antes de conseguir pintar a página.

Uma página lenta muitas vezes tem uma cascata nervosa: muitos arquivos pequenos, muitas origens e muitas descobertas tardias.

Arquivos menores ainda importam — só não igualmente

Este não é um argumento contra compressão ou otimização. É um argumento contra otimizar bytes enquanto se ignora a coordenação.

Arquivos menores importam mais quando o recurso é grande, bloqueia a renderização ou faz parte do caminho do conteúdo principal. Por exemplo:

  • A imagem hero deve ter tamanho e codificação adequados.
  • O CSS que bloqueia a renderização deve ser enxuto.
  • O JavaScript necessário para a primeira interação deve ser mínimo.
  • Fontes devem passar por subsetting, ser comprimidas e limitar-se aos pesos realmente usados.

Fontes são um exemplo comum. Equipes muitas vezes ficam obcecadas em saber se um arquivo de fonte tem 24 KB ou 31 KB, enquanto entregam seis pesos, dois estilos e várias famílias. A melhor correção não é cortar 7 KB de um arquivo. É enviar menos arquivos de fonte. Se tipografia faz parte do seu trabalho de performance, web fonts ainda são uma das vitórias mais fáceis na maioria dos sites.

Imagens seguem o mesmo padrão. AVIF ou WebP podem economizar bytes significativos, mas enviar dez imagens decorativas acima da dobra ainda é um plano ruim. Escolha formatos melhores, sim, mas também questione se cada imagem precisa ser requisitada. Para decisões de formato, nosso guia sobre quando AVIF supera WebP e quando não supera é um complemento útil a este trabalho de contagem de requisições.

Os custos ocultos de muitos arquivos pequenos

Muitas requisições pequenas tendem a criar problemas que não aparecem se você olha apenas para o total de bytes transferidos.

1. Descoberta tardia

Navegadores não podem requisitar o que ainda não descobriram. Um arquivo CSS pode referenciar uma fonte. Um script pode importar outro script. Um componente pode solicitar JSON depois da hidratação. Cada dependência cria mais uma etapa na cadeia.

Quanto mais profunda a cadeia, mais tarde o trabalho importante começa.

2. Sobrecarga de headers

Toda requisição e toda resposta incluem headers. A compressão de headers ajuda, especialmente em HTTP/2 e HTTP/3, mas não elimina a sobrecarga. Cookies podem piorar muito isso. Se seu site envia cookies grandes a cada requisição, assets minúsculos se tornam menos minúsculos na prática.

Esse é um motivo pelo qual assets estáticos muitas vezes devem ficar em caminhos ou domínios sem cookies, e por que headers de cache merecem atenção. Se os headers estão se comportando de forma estranha em produção, depurar redirects e headers HTTP costuma ser mais rápido do que adivinhar.

3. Interrupção da thread principal

Muitos chunks de JavaScript podem criar trabalho repetido de análise e execução. Mesmo que cada chunk seja pequeno, o navegador pode continuar parando para avaliar código. Isso pode prejudicar Interaction to Next Paint e fazer a página parecer instável.

O usuário não se importa que cada arquivo era pequeno. Ele se importa que tocar em um menu levou 600 milissegundos.

4. Complexidade de cache

Dividir assets pode melhorar o cache quando feito com cuidado. Um bundle de vendor estável e um bundle de app mutável podem ser uma boa divisão.

Mas chunking excessivo pode sair pela culatra. Mais arquivos significam mais consultas ao cache, mais oportunidades de revalidação, mais coordenação de versões e mais formas de invalidar acidentalmente recursos que não precisavam mudar.

Bundling voltou, mas com critério

A primeira era da performance web adorava bundling porque os navegadores tinham limites rígidos de conexão. Então o HTTP/2 chegou e muitas equipes foram com força para o code splitting agressivo. Parte disso foi útil. Parte virou superstição.

O meio-termo sensato é o bundling consciente de rotas.

Para um site típico de marketing ou conteúdo:

  • Faça inline ou carregue apenas o CSS necessário para a renderização inicial.
  • Mantenha o JavaScript global pequeno.
  • Evite dividir módulos minúsculos em requisições de rede separadas.
  • Adie recursos interativos que não são necessários imediatamente.
  • Remova scripts de terceiros que não justificam seu custo.

Para uma aplicação:

  • Divida por rota ou recurso principal, não por cada componente.
  • Mantenha dependências compartilhadas estáveis e cacheáveis.
  • Faça preload apenas dos recursos que definitivamente serão necessários em breve.
  • Evite carregar código de admin, dashboard, editor ou experimento em páginas públicas.
  • Meça o custo de interação, não apenas o tamanho do bundle.

Bundling não é automaticamente bom. Code splitting não é automaticamente bom. A pergunta útil é: esta divisão ajuda o navegador a entregar a próxima experiência significativa do usuário mais cedo?

Requisições de terceiros merecem desconfiança extra

Requisições de primeira parte pelo menos estão sob seu controle. Requisições de terceiros costumam ser mais lentas, menos previsíveis e mais caras do que parecem.

Um único tag manager pode acionar analytics, anúncios, heatmaps, widgets de chat, testes A/B, ferramentas de consentimento e scripts de personalização. Cada fornecedor pode trazer mais requisições. Alguns vão executar cedo. Alguns vão bloquear a thread principal. Alguns vão mudar sem passar pelo seu processo de release.

A melhor otimização de terceiros é a remoção. A segunda melhor é o adiamento.

Antes de adicionar um script de terceiro, pergunte:

  • Isso precisa carregar antes de o usuário ver a página?
  • Isso precisa carregar em todas as páginas?
  • Pode carregar depois de consentimento, interação ou tempo ocioso?
  • Quem é responsável por isso internamente?
  • Qual métrica prova que isso vale o custo de performance?

É aqui que performance vira governança. Alguém precisa ter permissão para dizer não.

Um checklist prático para reduzir requisições

Comece pelas páginas mais importantes: homepage, página de preços, página de produto, checkout, cadastro ou principais landing pages. Depois percorra a cascata.

Remover

  • Exclua JavaScript e CSS não utilizados.
  • Remova experimentos antigos, pixels abandonados e analytics duplicados.
  • Elimine pesos de fonte e bibliotecas de ícones não usados.
  • Substitua imagens decorativas por CSS quando apropriado.

Combinar com cuidado

  • Agrupe módulos JavaScript pequenos que sempre carregam juntos.
  • Mescle arquivos CSS pequenos que bloqueiam o mesmo caminho de renderização.
  • Use sprites SVG ou SVG inline para ícones repetidos quando isso reduzir requisições sem prejudicar a manutenibilidade.

Adiar

  • Faça lazy-load de imagens abaixo da dobra.
  • Adie scripts não críticos até depois da primeira pintura ou da interação do usuário.
  • Carregue comentários, embeds, mapas, chat e players de vídeo apenas quando necessário.

Cachear corretamente

  • Use cache de longa duração para assets estáticos versionados.
  • Evite revalidação desnecessária para arquivos que raramente mudam.
  • Mantenha o HTML atualizado, mas deixe assets com hash permanecerem em cache.

Medir novamente

Depois de cada mudança, verifique a cascata novamente. O objetivo não é uma pontuação perfeita. O objetivo é ter menos requisições críticas, renderização útil mais cedo e menos interrupção da thread principal.

Como é um bom resultado

Uma página saudável não necessariamente tem o menor número possível de requisições. Ela tem um caminho crítico pequeno e deliberado.

O navegador recebe HTML, CSS essencial, a imagem principal do conteúdo se houver uma, talvez um script pequeno necessário para navegação ou interação acima da dobra, e o conjunto mínimo de fontes necessário para tornar o texto legível. Todo o resto espera sua vez.

Essa é a diferença entre uma página que é apenas otimizada e uma página que parece rápida.

Reduzir arquivos ainda vale a pena. Mas, se o site já está razoavelmente comprimido, a próxima vitória de performance normalmente não é economizar mais 2 KB em um bundle. É uma requisição bloqueante a menos, um arquivo de fonte a menos, um script de terceiro a menos, uma cadeia de dependências a menos.

Menos requisições simplificam o trabalho do navegador. O simples é rápido com mais frequência do que gostamos de admitir.

Perguntas frequentes

Um bundle grande é melhor do que muitos arquivos pequenos?
Não automaticamente. Um bundle enorme pode atrasar tudo, especialmente no primeiro carregamento. Muitos arquivos minúsculos podem criar sobrecarga de agendamento e execução. O melhor padrão é agrupar recursos que sempre são necessários juntos e dividir por rota ou recurso principal.
HTTP/2 significa que a contagem de requisições não importa mais?
Não. HTTP/2 reduz parte da sobrecarga de conexão por meio de multiplexação e compressão de headers, mas cada requisição ainda tem custos de descoberta, priorização, servidor, cache, análise e execução.
Devo fazer inline de todo CSS crítico?
Fazer inline de uma pequena quantidade de CSS realmente crítico pode ajudar a primeira renderização, mas fazer inline de conteúdo demais deixa o HTML mais pesado e mais difícil de cachear. Mantenha no mínimo e meça o efeito.
Qual é o lugar mais fácil para reduzir requisições?
Fontes e scripts de terceiros costumam ser as vitórias mais rápidas. Muitos sites entregam pesos de fonte não usados, analytics duplicados, pixels antigos, widgets de chat ou embeds que não precisam carregar imediatamente.
Quantas requisições uma página deve ter?
Não há uma meta universal. Uma página pequena de conteúdo deve ter pouquíssimas requisições críticas. Uma aplicação complexa pode precisar de mais. Foque em reduzir requisições antes da primeira renderização e antes do caminho principal de interação.

Fontes e leituras adicionais

  1. MDN Web Docs: HTTP caching
  2. web.dev: Optimize Largest Contentful Paint
  3. RFC 9113: HTTP/2
  4. HTTP Archive Web Almanac: Page Weight
Sobre o autor
The Wux Webtools Team

Última atualização:

Continue lendo