- Critical CSS é a extração de apenas o CSS mínimo necessário para renderizar a "área visível inicialmente (above the fold)"; ao inseri-lo inline no HTML, há melhora nas Core Web Vitals, como o FCP (First Contentful Paint)
- Ele é inserido inline no
<head> do HTML para que o navegador possa renderizar o conteúdo rapidamente sem esperar pela folha de estilos completa
- Há benefícios como melhora na velocidade de carregamento percebida, aumento da pontuação no Lighthouse e melhorias em SEO e UX
- O CSS não essencial pode ser carregado com
<link> no fim do <body> ou com lazy loading via JavaScript para otimizar ainda mais o desempenho
- É importante observar que o usuário precisa ajustar manualmente os caminhos dos links CSS e as referências de assets
Critical CSS Generator
- Critical CSS Generator é uma ferramenta que extrai apenas o código CSS mínimo indispensável de uma página web, permitindo uma extração de CSS otimizada para o objetivo de uso
- Critical CSS são as regras mínimas de CSS necessárias para estilizar a área visível inicialmente da página
- Essa abordagem ajuda a melhorar o desempenho e as Core Web Vitals (como FCP), pois o navegador pode exibir o conteúdo principal imediatamente sem esperar o carregamento de todas as folhas de estilo
Por que usar?
- Sensação de carregamento inicial mais rápida
- Melhora na pontuação do Lighthouse
- Melhorias em SEO e experiência do usuário
🔧 Como aplicar
Step 1: Inserir o Critical CSS inline
Step 2: Carregamento tardio do CSS não essencial (método básico)
Step 3 (opcional): Carregamento assíncrono de estilos com JavaScript
- Após a conclusão do carregamento da página, use JavaScript para carregar dinamicamente o CSS não essencial
- Pode melhorar o desempenho quando a velocidade da rede for lenta
- Todas as tags
<link> de CSS não essencial existentes no <head> devem ser removidas
window.addEventListener("DOMContentLoaded", function () {
console.log("✅ Page loaded, now loading non-critical stylesheets...");
let stylesheets = [
// "/css/vendors.min.css",
// "/css/style.min.css",
];
let loadedCount = 0;
function checkAllStylesLoaded() {
loadedCount++;
if (loadedCount === stylesheets.length) {
console.log("✅ All non-critical stylesheets loaded...");
}
}
stylesheets.forEach(function (href) {
var link = document.createElement("link");
link.rel = "stylesheet";
link.href = href;
link.onload = checkAllStylesLoaded;
link.onerror = () => console.warn(`Failed to load stylesheet: ${href}`);
document.head.appendChild(link);
});
});
1 comentários
Comentários no Hacker News
Seria ótimo se também desse suporte a responsividade; a deduplicação de estilos críticos responsivos é difícil, então no fim eu sempre acabava editando a folha de estilos manualmente. Como o tamanho do CSS crítico importa, seria bom ter também uma opção para fazer down-compile de coisas como variáveis CSS. E não recomendo a orientação de colocar a tag
<link>do CSS não crítico antes de</body>, porque CSS precisa ser obtido rapidamente; desse jeito, a descoberta do CSS atrasa e o download também. Em vez disso, recomendo a combinação de preload com noscript:<link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'"><noscript><link rel="stylesheet" href="styles.css"></noscript>Fico na dúvida se esse método de usar código JS no preload não seria bloqueado por CSP, a menos que
unsafe-inlineesteja permitidoNão quero usar esse esquema de carregar CSS com hack em JS; ao aplicar a stylesheet, pode haver recálculo de layout/estilo da página inteira. O navegador busca stylesheet rapidamente mesmo quando ela está no fim da página
Dá para obter efeito parecido só com o atributo prefetch, hints em headers HTTP e combinação com CDN; nem precisa ficar rebuildando CSS crítico. Se usar direito uma CDN como a CF, fica muito rápido
Acho que faz sentido mesmo. Pretendo adicionar esse tipo de opção também. Em vez de "before body", testei a opção
DOMCONTENTLOADED, e ela funciona bem o bastante para UX e Lighthouse mesmo em celulares antigos e redes lentasConcordo totalmente com a sugestão de suporte a responsividade
Na minha opinião, isso parece otimização prematura demais. Pode ter valor quando o CSS é muito complexo ou quando há muitos recursos para carregar, mas na maioria dos casos é mais eficiente escrever CSS, HTML e JS de forma limpa, e essa abordagem pode ser desnecessária ou até prejudicial
É extremamente útil. Como freelancer, pego muitos sites em WordPress, e muitas vezes, depois de passarem por vários desenvolvedores/agências, o CSS/JS vira uma bagunça completa. Quero muito testar uma ferramenta assim
Quanto mais complexo o CSS ou quanto mais recursos houver, menor tende a ser o efeito líquido da otimização. O alvo aqui é otimizar latência de RTT; quanto maior o CSS crítico, maior o custo da otimização, então o ganho líquido diminui
Se fosse 12 anos atrás, eu teria pago por uma ferramenta dessas. Havia uma quantidade enorme de CSS acumulado ao longo de anos, e era difícil saber quais regras eram críticas
Para muitos sites, isso realmente pode ser otimização prematura. Mas, para sites sensíveis a cliques, como notícias/mídia, carregamento “instantâneo” da página é extremamente importante. Passou de 1 segundo, a taxa de abandono e a receita de anúncios caem. No HuffPost também tentaram essa otimização 10 anos atrás
Quando vejo a situação atual do desenvolvimento frontend, parece realmente exagerado. Ferramentas como Lighthouse fizeram as pessoas se fixarem em otimizar por números sem sentido, e o resultado é só mais complexidade no build; o usuário real nem percebe a diferença, mas desenvolver fica mais incômodo. Enquanto isso, ainda vejo com frequência sites cheios de erros bem básicos de UI/gerenciamento de estado. É frustrante
CSS, HTML e JS limpos são a resposta, mas às vezes você herda um projeto bagunçado ou usa um template, e mesmo desenvolvendo eu mesmo o design pode acabar se enrolando
Para mim, a forma de carregamento de CSS é algo que precisa ser considerado obrigatoriamente desde o início do desenvolvimento. Tivemos muitos clientes abandonando porque a nota no page speed test do nosso site era baixa. Como desempenho pesa em SEO, isso ficou importante demais. Eu redesenhei pessoalmente a otimização da página para tirar 100 no Google Lighthouse. É preciso planejar desde o começo a ordem e a forma de carregamento de CSS/JS para reduzir retrabalho depois. Nós até separamos CSS acima/abaixo da dobra e incluímos inline nos pontos adequados, e o JS abaixo da dobra nem é avaliado até haver scroll. Aplicamos tudo que o Lighthouse sugeria. O sistema anterior carregava em todas as páginas o CSS do site inteiro (3~4MB), e o JS era ainda pior. Foi consequência de não terem pensado em otimização desde o início. Ainda usamos esse sistema, então não posso citar o nome, mas internamente ele continua sendo fonte de problemas. Se desempenho é a meta, não acho que exista isso de otimização prematura; tudo tem que ser considerado desde o começo. Como resultado, temos nota 100 de desempenho para todos os clientes, inclusive no mobile, e estamos à frente dos concorrentes. Testei essa ferramenta no meu site, mas já estava tudo tão otimizado que ela não teve efeito, porque não havia mais o que melhorar
No meu caso, numa página feita com o framework Astro, o HTML tem 27.52KB (6.1KB comprimido), o JS fica abaixo de 10KB, e o CSS crítico tem 57KB (7KB comprimido). Sites parecidos vão de 100KB a 1MB. Se você fizer tudo de forma limpa, resource hints já bastam para ficar rápido sem CSS/JS inline. Com a combinação nginx+HTTP/2+edge cache, dá para ter desempenho 100/100 sem CSS crítico nem JS inline. Adicionar 7KB por página não me parece eficiente. Em termos de implementação, SPA/edge caching é muito mais ecológico e mais rápido. Não há necessidade de enviar HTML absurdamente pesado como no Elementor. A bateria do celular é limitada, então por que mandar dados desnecessários?
É um bom truque, mas agora que CDN e HTTP/2 já são comuns, esse tipo de otimização no fim só desperdiça banda. Melhora um pouquinho os números do benchmark, mas na prática acelera só uns 10~20ms
Incluir CSS crítico em todas as páginas não é necessariamente a resposta. Usar isso seletivamente só na primeira visita (sem cache) ou talvez na página inicial da sessão também é uma forma de evitar data bloat desnecessário
A pedido de um cliente, procurei uma ferramenta para extrair CSS crítico, mas as que encontrei não tinham o que eu queria, então acabei compartilhando uma solução própria feita com Puppeteer. Dá para definir quanto tempo esperar depois do carregamento da página. Também usei um serviço pago, mas não gostei e pedi reembolso. Feedback é bem-vindo; por enquanto está aberto e gratuito
Fiquei curioso se o problema era com ferramentas existentes como o pacote penthouse
Se você informar um site sem CSS, dá erro
O código está aberto? Eu gostaria de usar também como plugin de Vite/Astro
Queria perguntar se isso é uma versão com UI do penthouse, porque várias configurações parecem muito parecidas
Essa abordagem pode sair pela culatra; acontece um FOUC bem consistente (aquele flash sem estilos aplicados). Se o layout muda no meio, usuários que já estão clicando em algo podem ter um grande incômodo. Não é só um problema estético, é um problema real de usabilidade
Eu também fiz alguns ajustes de estilo depois de aplicar esse método, mas no fim ainda foi possível otimizar para CLS (cumulative layout shift) 0. Quando o orçamento é baixo e se usa um template com muitas bibliotecas, pode ser muito útil
O objetivo original não é justamente evitar FOUC sem bloquear a request de rede do CSS?
Essa abordagem faz mais sentido partindo da hipótese de que, na primeira visualização da página, não existe cache algum de CSS. Na prática, há trade-offs entre vários fatores, como proporção de visitantes novos/recorrentes, configuração de cache de CSS, CDN, 103 early hints, CSS crítico e initial congestion window
Ao medir desempenho em localhost, o impacto do CSS foi quase inexistente. Mesmo removendo completamente o CSS, a melhora ficou abaixo de 7ms, e ainda dentro da margem de erro da medição
Usei essa ferramenta no meu site e ela extraiu para o CSS até elementos de debugging que não eram realmente necessários. Por exemplo,
body::afterpara overlay de grade do site também acabou entrando no CSS (eu tinha até esquecido disso, e só percebi agora)Eu prefiro escrever HTML que transmita bem o significado mesmo sem CSS. Isso ajuda a evitar que a estrutura do documento fique complexa demais desde cedo
A ideia em si é interessante, então testei no meu site pessoal, mas apareceu um erro de omissão de CSS na biblioteca penthouse:
{"error":true,"name":"Error","message":"css should not be empty" ...}