Render-blocking requests no Lighthouse: como corrigir

O Lighthouse 13 lista todas as folhas de estilo e scripts pelos quais a página espera antes do primeiro paint, inclusive os rápidos. Quando isso custa tempo aos visitantes e quais correções de CSS funcionam.

Arjen Karel Core Web Vitals Consultant
Arjen Karel - linkedin
Last update: 2026-10-17

Requests render-blocking prejudicam o score?

O Lighthouse lista todas as folhas de estilo e scripts pelos quais a página esperou antes do primeiro paint no insight Render-blocking requests ("As solicitações estão bloqueando a renderização inicial da página, o que pode atrasar o LCP"), chamado de "Eliminate render-blocking resources" antes do Lighthouse 13. O insight não conta para o score, mas enquanto a página espera pelo CSS e pelos scripts, a tela fica branca, o que atrasa o FCP e o LCP, principalmente no celular. Enxugue e combine o CSS e adie os scripts.

O que o insight Render-blocking requests verifica?

A descrição do Lighthouse diz: "As solicitações estão bloqueando a renderização inicial da página, o que pode atrasar o LCP. O adiamento ou a inserção inline podem remover essas solicitações de rede do caminho crítico." Fazer inlining não é a solução: veja abaixo. A tabela tem três colunas: URL, Transfer Size e Duration. Transfer Size é o arquivo como foi enviado, compactado. Duration é a estimativa do Lighthouse de quanto tempo o request leva em um celular lento, incluindo uma nova conexão com outro domínio.

Enquanto carrega uma página, o Chrome marca cada request como render-blocking ou não e grava isso no trace. O Lighthouse lê o trace e lista todos os requests no frame principal que o Chrome marcou como bloqueadores e que terminaram antes do primeiro paint. Na prática, são as folhas de estilo e os scripts síncronos no <head> e os arquivos que eles puxam com @import. Uma folha de estilo no body só conta na prioridade mais alta do Chrome, e um script na prioridade alta; depois da primeira imagem, ambos caem de prioridade e são ignorados. Não há limite: um único arquivo listado já reprova no insight.

Alguns arquivos nunca aparecem, mesmo quando deixam a página mais lenta: scripts async, arquivos que um script adiciona à página (gtm.js, gtag.js), estilos e scripts inline, qualquer coisa em um iframe e fontes.

Lighthouse 13.5.0 report with the Render-blocking requests insight expanded: Est savings of 1,140 ms, labels FCP, LCP and Unscored, twelve requests with URL, Transfer Size and Duration, several Duration cells empty

O insight em uma página de produto do WooCommerce, Lighthouse 13.5.0, throttling simulado como no PageSpeed Insights.

O que torna um arquivo render-blocking?

Render-blocking significa que o navegador não renderiza nada até o arquivo chegar: toda folha de estilo no <head> precisa chegar e todo script síncrono nele precisa ser baixado e executado.

  • Um script depois de uma folha de estilo espera por ela. O Chrome não executa um script síncrono até o CSS acima dele chegar, e o parser espera pelo script. Os dois arquivos podem ser baixados em paralelo, mas você ainda paga o tempo do CSS e depois o do script.
  • Um @import começa tarde. O preload scanner do Chrome encontra todos os links no HTML de uma vez, mas só encontra um @import dentro de um arquivo CSS quando esse arquivo chega. Na página de produto abaixo, a folha de estilo importada do tema começou em 1,28 s, contra 0,59 s quando estava linkada diretamente no HTML.
  • Outro domínio custa uma conexão. Uma folha de estilo no fonts.googleapis.com ou em uma CDN precisa de DNS, TCP e TLS antes que seu primeiro byte chegue.
No ChromeBloqueia o primeiro paint?
<link rel="stylesheet"> no headSim
o mesmo com fetchpriority="low"Sim
o mesmo com media="print"Não, mas ainda é baixado
rel="preload" mais um link de folha de estilo para o mesmo arquivoSim
@import em uma folha de estilo bloqueadoraSim, depois do arquivo pai
<script src> no headSim
asyncNão, mas pode executar antes do paint
defer, type="module"Não
uma folha de estilo no bodyApenas o conteúdo abaixo dela

Requests render-blocking afetam o FCP e o LCP?

Fiz a medição em uma página de produto do WooCommerce com nove folhas de estilo e dois scripts no head, em um celular em Slow 4G. Na versão corrigida, o CSS foi enxugado e combinado em uma única folha de estilo de 6,6 kB e os dois scripts usam defer. Depois de carregada, ela fica exatamente igual.

FCP

A versão original teve o primeiro paint em 2,12 s; a versão corrigida, em 1,39 s.

The product page before the fix on a phone at 1.4 seconds: a white screen

Antes

The product page after the fix on a phone at 1.4 seconds: the styled page is there, the product photo still loading

Depois

Ambas as versões em 1,4 s no celular com throttling: a original ainda está branca.

LCP

O LCP não pode acontecer antes do primeiro paint. Aqui o elemento do LCP é a foto do produto, e ela também não pode aparecer antes do CSS chegar: o LCP foi de 2,25 s para 1,91 s com o fix. Em um detalhamento do LCP, essa espera aparece como element render delay. O Lighthouse não mostra isso: com uma imagem como elemento do LCP, ele sempre estima a economia de LCP em 0 ms, então não interprete isso como ausência de efeito no LCP.

Quantos sites são afetados e é seguro ignorar?

Quase todos. O State of CWV analisa a home page de 114.526 sites com dados do CrUX: 92,8% têm pelo menos um request render-blocking, 91,2% têm uma folha de estilo bloqueadora e 62,5% têm um script bloqueador. Onde eles existem, a mediana é de 8 requests e 110 kB, e um em cada cinco sites tem mais de 20. (O State of CWV conta folhas de estilo e scripts síncronos no head, o que bate de perto com a lista do Lighthouse.)

Sites com muitos deles têm desempenho pior em campo. 84,0% dos sites sem nenhum request desse tipo têm um bom FCP em celulares, contra 54,1% dos sites com mais de 20. Mas o servidor explica a maior parte dessa queda: na mesma faixa, a mediana do TTFB dobra, passando de 538 ms para 1.114 ms. Dividindo pela velocidade do servidor:

Chart: share of sites with a good FCP on phones by number of render-blocking requests, green bars for a fast server staying around 95% and red bars for a slow one falling to 30% at 21 or more

Sites com um bom FCP em celulares por número de requests render-blocking e tempo de resposta do servidor. State of CWV, outubro de 2026, CrUX p75 em celulares, FCP bom é de 1,8 s ou menos.

  • Servidor rápido (TTFB abaixo de 600 ms): de 94% a 97% têm um bom FCP, não importa a quantidade. A perda de tempo continua lá: do primeiro byte ao primeiro paint leva cerca de 150 a 200 ms a mais com 21 ou mais requests bloqueadores do que sem nenhum.
  • Servidor lento (TTFB de 900 ms ou mais): a taxa de FCP bom cai de cerca de metade dos sites (47% a 53%) com até dois requests bloqueadores para 30% com 21 ou mais. Com um TTFB de 900 ms ou mais, sobram menos de 0,9 s antes do limite de 1,8 s para um FCP bom, então qualquer request extra pelo qual o paint espera pode estourar o FCP.

Sites em WordPress têm mais deles: 57% têm 16 ou mais requests bloqueadores (mediana de 19, 163 kB). Na mesma velocidade de servidor, isso custa 3 pontos de FCP bom contra um a cinco requests em um host rápido, e cerca de 10 pontos em um lento.

Isso é uma correlação, mas define a ordem: com um TTFB lento, resolva o servidor primeiro. Em um servidor rápido, ainda vale a pena buscar esses 150 a 200 ms quando o CSS é seu. Você pode ignorar o aviso quando:

  • o Lighthouse lista apenas uma ou duas folhas de estilo próprias e pequenas, cada uma abaixo de cerca de 15 kB;
  • o arquivo listado é uma ferramenta de consentimento, um snippet de teste A/B ou um arquivo da plataforma que você não pode alterar (veja abaixo).

Como identificar requests render-blocking nos field data?

O Lighthouse carrega a página uma única vez, do zero. Depois da primeira página, os visitantes já têm o CSS no cache, então nos field data o custo aparece principalmente na primeira página que um visitante carrega. No CoreDash, observe dois pontos no celular:

  • FCP ao lado do TTFB. Arquivos render-blocking cobram seu tempo entre o primeiro byte e o primeiro paint. Um template onde essa diferença é maior do que nos outros carrega mais arquivos desse tipo.
  • LCP render delay. Procure templates onde o render delay represente uma parte grande do LCP. O CSS bloqueador é uma das causas dessa espera; o DevTools (próxima seção) mostra se a página tem algum.

O CrUX tem as mesmas métricas no p75 para a sua origem ou uma URL, mas sem informar qual template é o lento.

CoreDash on mobile: First Contentful Paint at p75 per URL, the product and category pages in amber

CoreDash em uma loja de exemplo, acme-pagespeed.com, celular, p75: as páginas de produto e de categoria são as lentas.

Como encontrar os arquivos bloqueadores no DevTools?

Abra a página no Chrome, vá para o painel Performance, configure a rede para Slow 4G e a CPU para 4x slowdown e grave um recarregamento. A barra lateral Insights lista os Render-blocking requests. Clique nela e o DevTools destacará cada request bloqueador na trilha Network.

Chrome DevTools Performance panel with the Render-blocking requests insight open, the blocking requests outlined in the Network track and the FCP marker after the last one

Cada barra vai do momento em que o request começou até a chegada do seu último byte. Procure o request que termina por último antes do marcador de FCP: o paint esperou por ele. Um request de CSS que só começa quando outro termina é um @import. Quando nada bloqueia, a barra lateral mostra "No render-blocking requests for this navigation".

Como corrigir requests render-blocking?

A URL na tabela do Lighthouse indica de onde vem cada arquivo, e isso define onde você deve fazer a alteração.

CSS e scripts próprios

Nos seus próprios templates, mire nesta estrutura de head: uma folha de estilo única, pequena e enxuta, e todos os scripts com defer. Assim, o primeiro paint espera apenas por esse arquivo.

<link rel="stylesheet" href="/css/main.min.css">
<script src="/js/jquery.min.js" defer></script>
<script src="/js/gallery.min.js" defer></script>

O passo a passo para chegar lá está mais abaixo, começando por Enxugue e combine o CSS.

WordPress

Arquivos em /wp-content/plugins/ pertencem a um plugin, em /wp-content/themes/ ao seu tema e em /wp-includes/ ao próprio WordPress.

Se você não programa, use um plugin de otimização com estas configurações:

  • Ative o adiamento dos scripts: Load JavaScript deferred no WP Rocket, Defer JavaScript no Perfmatters, Load JS Deferred no LiteSpeed Cache. Um script com defer não trava mais o primeiro paint. O jQuery exige cuidado, veja abaixo.
  • Deixe o Load CSS Asynchronously e o critical CSS desativados, não importa o que a dica antiga do WordPress sob este insight diga sobre plugins que "fazem inline de recursos críticos". O critical CSS até funciona, mas o restante do CSS chega depois do primeiro paint, fazendo a página ser estilizada duas vezes e frequentemente sofrer layout shift. O custo adicional do inlining está explicado em Enxugue e combine o CSS.
  • Deixe o Remove Unused CSS desativado (Generate UCSS no LiteSpeed Cache). Ele gera um CSS separado para cada URL (o WP Rocket insere inline no HTML) e mantém apenas as regras encontradas na página durante o carregamento; assim, um elemento que um script altera mais tarde (um menu aberto, um slider) pode perder seus estilos. O WP Rocket tem um guia inteiro dedicado aos problemas de exibição que isso causa. É mais dor de cabeça do que benefício: enxugue e combine as folhas de estilo manualmente. Dá mais trabalho, mas compensa.

Muitos plugins carregam seu CSS em todas as páginas, inclusive onde não fazem nada: Contact Form 7 em páginas sem formulário, WooCommerce fora da loja. Toda folha de estilo impressa pelo WordPress tem um id como contact-form-7-css: a parte antes de -css é o identificador (handle) que você usa para removê-la onde não for necessária:

add_action( 'wp_enqueue_scripts', function () {
  if ( ! is_page( 'contact' ) ) {
    wp_dequeue_style( 'contact-form-7' );
  }
}, 20 );

O WooCommerce tem seu próprio filtro para as suas três folhas de estilo, o woocommerce_enqueue_styles. Para scripts próprios, o WordPress 6.3 e versões superiores permitem adicionar defer:

wp_enqueue_script( 'acme-gallery', get_stylesheet_directory_uri() . '/js/gallery.min.js', array( 'jquery' ), '2.3.0', array( 'strategy' => 'defer' ) );

O WordPress remove esse defer sem aviso quando um script que depende do seu ainda for bloqueador, ou quando um script inline for inserido depois dele. Verifique a tag de script no código-fonte da página.

Só adie o jQuery com uma ferramenta que também lide com chamadas inline jQuery(...). O WordPress registra o jQuery sem defer, então ele bloqueia o head assim que qualquer elemento depende dele, e adicionar defer manualmente quebra todas as chamadas inline jQuery(...) executadas antes dele. A opção Load JavaScript deferred do WP Rocket adia o jQuery e encapsula essas chamadas inline. O Defer JavaScript do Perfmatters deixa o jQuery de fora até que você ative Include jQuery; ao fazer isso, navegue pela página (menu, galeria, carrinho) para verificar se nada quebrou.

Um tema filho cujo style.css começa com @import url("../storefront/style.css") cria uma cadeia de @import. Remova essa linha e carregue a folha de estilo pai com wp_enqueue_style.

Shopify

Os apps adicionam seus arquivos por meio de app embeds (Loja virtual, Editar tema, App embeds). O arquivo de script de um embed carrega em async (a menos que seu Liquid escreva sua própria tag de script), mas a folha de estilo bloqueia a renderização. Desative os embeds que você não usa e, após desinstalar um app, procure no theme.liquid e nos snippets pelo código que ele deixou para trás.

Os temas carregam seu CSS com o filtro stylesheet_tag no theme.liquid, que gera um link bloqueador. Para a folha de estilo base principal, não há problema. O filtro script_tag gera um script sem defer, então escreva essa tag manualmente:

<!-- blocks the first paint -->
{{ 'gallery.js' | asset_url | script_tag }}

<!-- doesn't -->
<script src="{{ 'gallery.js' | asset_url }}" defer></script>

A Shopify já envia 103 Early Hints para até 10 arquivos render-blocking no head, portanto esses arquivos já começam a carregar cedo de qualquer forma; o que você ainda pode mudar é a quantidade e o tamanho deles. A folha de estilo do accelerated checkout deve continuar na lista (veja abaixo).

Next.js

No App Router, toda importação de CSS se torna uma tag de link de folha de estilo no topo do head, e o React não renderiza até que ela seja carregada. O Next.js agrupa esses arquivos em alguns chunks, portanto o fix é ter menos CSS. Mova o CSS que apenas algumas rotas utilizam do CSS global para CSS Modules: o CSS global importado no layout raiz vai para todas as rotas; um CSS Module vai apenas para as rotas que o importam. Veja mais sobre como o Next.js cria seus arquivos CSS.

O Next.js carrega seus próprios scripts de forma assíncrona ou com defer. Um script bloqueador em um site Next.js geralmente foi adicionado ao layout manualmente. Carregue-o com o next/script, que por padrão só o carrega depois que o Next.js inicia a hidratação da página:

import Script from 'next/script'

<Script src="https://example.com/widget.js" strategy="afterInteractive" />

Google Fonts e outros domínios

O link do Google Fonts é uma folha de estilo bloqueadora em fonts.googleapis.com, e os arquivos de fonte vêm de um segundo domínio, fonts.gstatic.com. O Lighthouse atribuiu a esse arquivo de 0,5 kB a maior Duration: ele contabiliza a nova conexão. Hospede você mesmo as fontes e coloque as regras @font-face na sua própria folha de estilo para eliminar o request e ambas as conexões. No Next.js, o next/font já faz isso.

Ferramentas de consentimento, testes A/B e outros arquivos para não mexer

  • Uma ferramenta de consentimento com auto-blocking (Cookiebot, OtAutoBlock da OneTrust, autoblocker da Usercentrics): ela precisa rodar antes de qualquer outro script para conseguir bloqueá-los, portanto é síncrona por design. A alternativa é o modo manual, onde você mesmo marca cada script de cookie. Se isso compensa o trabalho, é antes de tudo uma questão jurídica. Um preconnect para o domínio da ferramenta ao menos inicia a conexão mais cedo.
  • Um snippet de teste A/B (Optimizely, AB Tasty, Convert): é síncrono de propósito, para que os visitantes não vejam a versão original piscar antes da variante. Remova-o quando nenhum teste estiver em execução.
  • O content_for_header da Shopify: todo tema precisa dele e você não pode editá-lo. Em todas as cinco lojas verificadas para esta página, ele adicionou uma folha de estilo bloqueadora para o accelerated checkout, a accelerated-checkout-backwards-compat.css. Deixe como está.

Enxugue e combine o CSS

Mantenha o CSS render-blocking restrito a poucas folhas de estilo, cada uma com menos de cerca de 15 kB compactada. 15 kB é aproximadamente o que uma nova conexão entrega em seu primeiro round trip.

Chrome DevTools Network waterfall on Slow 4G: four 0.3 kB stylesheets that are almost all waiting time, a 14 kB stylesheet with a short download and a 60 kB stylesheet with a long one

Seis folhas de estilo render-blocking em Slow 4G no painel Network do DevTools. Em verde está a espera pelo primeiro byte, igual para todos os arquivos. Em azul está o download, que cresce conforme o tamanho do arquivo.

  • Combine os arquivos minúsculos adicionados pelo seu tema e plugins. Toda folha de estilo espera um round trip completo antes do primeiro byte chegar, cerca de 0,6 s em Slow 4G, não importa o tamanho. Um arquivo de 0,3 kB paga essa espera inteira por quase nada.
  • Enxugue ou divida arquivos grandes. Após a mesma espera, o arquivo de 14 kB foi carregado 0,4 s depois. O arquivo de 60 kB precisou de mais um segundo para baixar, e a tela continuou branca até ele chegar.
  • Remova as regras que a página não usa. A aba Coverage no DevTools mostra, por arquivo, quanto do CSS a página nunca utiliza. Na mediana dos sites, esse valor é de 89% (State of CWV, cobertura do Chrome na home page).
  • Não coloque todo o CSS em um único arquivo gigante. Todo o CSS, sem ser enxugado, em um arquivo de 68 kB teve o paint mais tarde do que os nove arquivos separados. O arquivo grande dividiu a largura de banda com os scripts adiados e a imagem de destaque (hero image), enquanto com nove arquivos os requests render-blocking ficaram com a maior parte dela.
  • Não faça inlining do CSS. O CSS inline vai para o HTML, e o HTML é o primeiro arquivo de que o navegador precisa: tudo o mais espera por ele. Portanto, o inlining deixa o único arquivo pelo qual todos esperam maior e mais lento. Mais importante ainda: o navegador geralmente não consegue armazenar o HTML em cache, fazendo com que cada visualização de página baixe esse CSS novamente, enquanto uma folha de estilo separada fica no cache após a primeira página. Entre sites com TTFB abaixo de 900 ms e de um a cinco requests bloqueadores, 95,9% dos que não usam CSS inline têm um bom FCP, contra 90,8% dos que inserem mais de 300 kB inline (State of CWV).
  • Não separe "o restante" do CSS para carregar depois. O velho truque do media="print" só funciona para CSS que nunca está na primeira tela, e você raramente tem certeza disso para todas as páginas e tamanhos de tela: se errar na previsão, a página renderiza sem estilos primeiro.

Substitua todo @import

Dê a cada arquivo importado sua própria tag de link no HTML ou combine-o diretamente no arquivo pai. Remover o @import na página de produto adiantou o primeiro paint em 137 ms assim que os scripts foram adiados com defer. Com os scripts ainda bloqueando, a economia foi de 33 ms: o jQuery chegou quase ao mesmo tempo que a folha de estilo importada, então o paint esperou pelo jQuery de qualquer maneira.

Adie os scripts

Adicione defer a todo script no head de que o primeiro paint não precisa. Scripts do tipo module já vêm com defer por padrão. O async também remove o script da lista, mas ele ainda pode executar antes do primeiro paint e travar a main thread; por isso, o defer é um padrão melhor. Hoje, os scripts representam a menor parte desse insight: adiar ambos os scripts rendeu 24 ms, porque o CSS terminou mais tarde de qualquer forma. Saiba mais em async vs defer, JavaScript no head vs no footer e 14 métodos para adiar o JavaScript.

Carregue a folha de estilo principal mais cedo com 103 Early Hints

Com o 103 Early Hints, o servidor avisa ao navegador quais arquivos buscar enquanto ainda está gerando o HTML. Envie o hint da sua folha de estilo principal:

HTTP/2 103
link: </css/main.min.css>; rel=preload; as=style

Isso compensa quando o servidor precisa de tempo para montar a página. A folha de estilo é baixada durante esse período, então o ganho se limita, no máximo, ao tempo de processamento do servidor, e uma página servida pelo cache da CDN ganha pouco. A Cloudflare tem uma opção para isso (Speed, Settings, Content Optimization) e gera os hints a partir dos cabeçalhos Link enviados pelo seu servidor. O Apache 2.4.58 e versões superiores contam com o H2EarlyHint.

Verifique o LCP em seguida. Com o CSS chegando mais cedo, as fontes declaradas nele também começam antes: na página de produto, a fonte de 156 kB do Font Awesome disputou largura de banda com a foto do produto, e o LCP acabou atrasando. O Lighthouse mantém o arquivo indicado pelo hint na lista de qualquer forma, com 0,0 KiB. Veja mais sobre 103 Early Hints e sobre por que um preload simples de uma folha de estilo que você também linka não ajuda.

Evite fetchpriority="low" em folhas de estilo

Uma dica comum é aplicar fetchpriority="low" ao CSS de que a primeira tela não precisa. Isso é um antipadrão. No head, o Chrome rebaixa essa folha de estilo apenas um nível, de prioridade highest para high, e ainda espera por ela antes do primeiro paint. O Lighthouse decide o que bloqueia a renderização com base na prioridade em sua simulação, tratando o arquivo como se ele nem existisse: sem Duration e com um FCP simulado mais rápido.

Fiz o teste em quatro folhas de estilo. O Lighthouse com throttling simulado reduziu o FCP de 2,03 s para 1,60 s e subiu o score de 96 para 97. No Chrome, o primeiro paint foi de 2.122 ms para 2.114 ms, ou seja, os visitantes continuam esperando o mesmo tempo de antes.

Lighthouse report of the product page with fetchpriority low on four stylesheets: score 97, FCP 1.6 s, Render-blocking requests still red with Est savings of 800 ms

Lighthouse, throttling simulado

The same page in Chrome on a phone at the moment Lighthouse reports its FCP: still a white screen

Chrome no celular, mesma página

No momento que o Lighthouse aponta como FCP, o Chrome ainda exibe uma tela branca.

Como verificar se o fix funcionou?

Execute o Lighthouse no mobile novamente. Com o fix, o score subiu de 96 para 100 e o FCP simulado caiu de 2,0 s para 1,1 s, e o insight passou de vermelho com doze arquivos para laranja com apenas um: a folha de estilo de 6,6 kB.

Lighthouse report before the fix, on a phone: score 96, FCP 2.0 s, Render-blocking requests red with Est savings of 1,140 ms

Antes

Lighthouse report after the fix, on a phone: score 100, FCP 1.1 s, Render-blocking requests orange, without Est savings

Depois

Lighthouse 13.5.0, mobile, throttling simulado.

Execute o teste três vezes e considere o resultado intermediário: na mesma página, o FCP simulado variou 1,5 s entre as execuções.

O CoreDash mostra o FCP e o LCP render delay a partir das visitas seguintes. O CrUX e o Search Console mostram os últimos 28 dias; assim, duas semanas após o fix, metade do que eles exibem ainda reflete o site antigo.

Quer saber se o CSS bloqueador é o que mantém o seu FCP ou LCP no vermelho no celular? Em uma power hour de Core Web Vitals, analisamos juntos os seus field data e um trace da sua página, e você sai com a lista dos arquivos que precisa enxugar, combinar ou adiar.

About the author

Arjen Karel is a web performance consultant and the creator of CoreDash, a Real User Monitoring platform that tracks Core Web Vitals data across hundreds of sites. He also built the Core Web Vitals Visualizer Chrome extension. He has helped clients achieve passing Core Web Vitals scores on over 925,000 mobile URLs.

 

CoreDash já vem com MCP.

Conecta no Claude ou em qualquer agente de IA. Pergunta pra ele por que seu INP disparou terça passada.

Vê como funciona
Render-blocking requests no Lighthouse: como corrigir Core Web Vitals Render-blocking requests no Lighthouse: como corrigir