7 pontos por GN⁺ 2025-05-15 | 1 comentários | Compartilhar no WhatsApp
  • 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

  • Insira o Critical CSS dentro da tag <style> e posicione-o no topo do <head> do HTML
  • Ele deve vir antes de outras folhas de estilo ou scripts
  • Os caminhos internos dos assets podem precisar de ajuste conforme necessário
    <style>  
      /* Critical CSS for your page */  
      /* ... CSS content ... */  
    </style>  
    

Step 2: Carregamento tardio do CSS não essencial (método básico)

  • Remova a tag <link> original do <head> e coloque-a logo antes de </body>
  • Assim, a renderização inicial acontece apenas com o Critical CSS, e o CSS não essencial é carregado depois
    <html>  
      ...  
      <body>  
        ...  
        <link rel="stylesheet" href="/css/vendors.min.css">  
        <link rel="stylesheet" href="/css/style.min.css">  
      </body>  
    </html>  
    

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

 
GN⁺ 2025-05-15
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-inline esteja permitido

    • Nã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 lentas

    • Concordo 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

    • Sim, é algo voltado para a primeira entrada e mais um trade-off do que algo que eu recomendaria de verdade. O melhor mesmo é escrever todo o código e os estilos à mão e reduzir o uso de bibliotecas
  • 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

    • Otimização de desempenho de latência cliente-servidor naturalmente não faz sentido em ambientes de baixa latência como localhost. Não acho que essa otimização seja obrigatória, mas testar em localhost não é um bom benchmarking
  • 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::after para 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

    • Mas isso não se aplica a todos os sites. Por exemplo, há muitas UIs em que leitura da esquerda para a direita e de cima para baixo não é o padrão
  • 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" ...}

    • Vou verificar esse caso também, obrigado