Minificador de CSS

Comprima CSS removendo comentários e espaços, e otimizando os valores.

Sobre a minificação CSS

É tentador supor que, como o Brotli comprime fluxos de texto tão agressivamente, o valor marginal de uma passagem de minificação separada desabou. O blog de engenharia da Sentry fez exatamente esse argumento em abril de 2024 e concluiu o oposto: a minificação ainda compensa. Com a velocidade média global da internet móvel em torno de 53 Mbps e o Brotli implantado universalmente na borda do CDN, «se conseguir raspar apenas 1 KB de um total de 100 recursos a cada carregamento de página, pode estar a fazer uma melhoria de 15 ms na velocidade da página para esses utilizadores». Multiplicado pela base de visitantes de qualquer site não trivial, isso torna-se uma factura real de largura de banda, um custo real de bateria em dispositivos móveis e uma mudança real de posição num relatório Lighthouse.

O mecanismo importa. Gzip e Brotli são compressores sem perdas de uso geral que procuram sequências de bytes repetidas e codificam cada repetição como uma referência para trás num dicionário de janela deslizante. Dois ficheiros CSS que produzam o mesmo comportamento de navegador mas contenham bytes diferentes serão comprimidos para dois tamanhos diferentes. margin: 10px 10px 10px 10px; e margin:10px são semanticamente idênticos, mas o primeiro tem mais caracteres a serem codificados mesmo que muitos sejam repetições, o Brotli é bom a encontrar repetição mas não compreende que duas cadeias CSS sintacticamente distintas exprimem a mesma regra. Apenas um minificador com consciência de CSS pode fazer isso. O hub de aprendizagem da Cloudflare situa as reduções típicas de texto bruto entre 30-50 %; o Brotli por cima acrescenta mais uns modestos 5-15 %, mas não é zero, e à escala soma.

O CSS bloqueia a renderização, e é por isso que os bytes contam

O Largest Contentful Paint é um dos três Core Web Vitals; o limiar para «Bom» é 2,5 segundos no percentil 75 dos carregamentos de página. A pontuação global de Performance do Lighthouse pondera o LCP em 25 % do total. O CSS bloqueia a renderização por defeito, quando o navegador vê um <link rel="stylesheet">, pausa a renderização até esse ficheiro ser descarregado e o CSSOM construído, porque regras posteriores na folha de estilo podem sobrepor-se a regras anteriores e o navegador não pode arriscar pintar num estado sem estilo ou mal estilizado. O CSS Object Model, ao contrário do DOM, não é construído incrementalmente, o analisador precisa da folha inteira para saber que regras vencem. O JavaScript também bloqueia nisto: os scripts não podem correr em segurança enquanto o CSSOM estiver incompleto. A implicação prática é que cada byte de CSS bloqueador de renderização está no caminho crítico de cada Core Web Vital. Um bundle minificado de 100 KB poupa-lhe talvez 30 ms numa ligação 4G rápida em comparação com um não-minificado de 150 KB, pequeno por página, mas o estudo de caso da Vodafone mostrou um aumento de 8 % nas vendas a partir de uma melhoria de 31 % no LCP. O efeito de segunda ordem é ainda maior: um LCP mais rápido aumenta as pontuações Lighthouse, o que aumenta a visibilidade na pesquisa Google para sites onde os Web Vitals são um sinal de classificação conhecido.

O que um minificador CSS faz realmente

Minificador vs optimizador, a linha seguro-vs-agressivo

A documentação do cssnano distingue entre o seu preset «default» (apenas transformações seguras) e o seu preset «advanced» (transformações agressivas que dependem de pressupostos sobre o seu CSS). O preset por defeito é o que se activa sem pensar; o preset advanced é o que se activa após auditoria, porque algumas optimizações podem partir código que dependa de comportamento subtil de cascata, prefixos de fornecedor ou peculiaridades do navegador. Transformações advanced podem reordenar regras dentro de uma folha de estilo para melhorar a compressibilidade, arriscado se tiver fallbacks intencionais de propriedades duplicadas como display: flex; display: grid;. Podem fundir corpos de regras idênticos em listas de selectores separadas por vírgulas. Podem remover como código morto declarações sobrescritas, com a mesma ressalva de fallback. Podem normalizar valores display, funções de transformação e identificadores personalizados, translate3d(0,0,0) pode simplificar para translate(0) se não depender do efeito secundário de promoção a GPU. Podem remover prefixos de fornecedor não usados com base num alvo Browserslist. O csso (Yandex, 2011) descreve-se como um «optimizador estrutural» em vez de um minificador puro, com três categorias de transformação: limpeza, compressão e reestruturação. O Lightning CSS descreve a mesma divisão: uma passagem «minify» que é sempre segura, mais um conjunto de transformações targets-aware que compilam CSS moderno para o que os navegadores mais antigos compreendem. A linha honesta: um minificador é o que se pode aplicar a qualquer ficheiro CSS sem pensar; um optimizador é o que se aplica com conhecimento da sua codebase.

Uma breve história das ferramentas de minificação CSS

YUI Compressor (2007). Julien Lecomte da Yahoo anunciou o YUI Compressor a 11 de Agosto de 2007. A versão original tratava apenas de JavaScript; três dias depois, a versão 2.0 adicionou suporte CSS integrando um minificador CSS baseado em regex originalmente escrito por Isaac Schlueter para uso pessoal. O YUI Compressor foi o padrão de facto durante vários anos, especialmente nos mundos Java/Maven e Rails-asset-pipeline; ainda é usado hoje, embora a própria biblioteca YUI tenha sido descontinuada pela Yahoo em 2014. O lado CSS do YUI Compressor sempre foi baseado em regex, não em AST, uma decisão de design cujas consequências ecoam nas ferramentas mais pequenas do lado do navegador que se seguiram.

clean-css (2011). Jakub Pawlowicz publicou o clean-css sob a organização GoalSmashers no GitHub em 2011, apresentando-o como «optimizador CSS rápido e eficiente para Node.js e a Web». Foi o primeiro grande minificador CSS concebido especificamente para o ecossistema Node.js e tornou-se o padrão em pipelines Grunt e Gulp. A linha 5.x actual atrai aproximadamente 21 milhões de downloads semanais do npm, suporta inlining de @import, rebasing de URL e source maps, e tem um modelo escalonado de «níveis de optimização» que torna explícita a divisão seguro-vs-agressivo. csso (2011) originou-se como projecto interno da Yandex, publicado com copyright 2011 por Sergey Kryzhanovsky baseado numa ideia de Vitaly Harisov. cssnano (Abril de 2015) de Ben Briggs adoptou uma abordagem diferente: em vez de um minificador monolítico, o cssnano é um pacote curado de pequenos plugins PostCSS (~30 no preset por defeito). Tornou-se o minificador CSS dominante no ecossistema JavaScript em grande parte por causa desta componibilidade e porque o próprio PostCSS (a framework de Andrey Sitnik, lançada pela primeira vez em Novembro de 2013) tornou-se o substrato para tanta outra coisa (Autoprefixer, Stylelint, o pipeline de processamento do Tailwind). O cssnano está agora na versão 7.x e é o minificador CSS por defeito no css-minimizer-webpack-plugin do webpack, no Next.js e em muitos outros padrões de framework.

O minificador CSS do esbuild (2020-2021). Evan Wallace, co-fundador da Figma, publicou o esbuild como «um projecto de hobby que escrevi durante as férias de inverno de 2019-2020». Escrito em Go, o esbuild era 10-100× mais rápido que os bundlers baseados em JavaScript da época. O suporte CSS amadureceu ao longo de 2021; é agora ubíquo como minificador subjacente no Vite, no tsup, em incontáveis templates de framework. Lightning CSS (2021/2022). Devon Govett, criador do Parcel, anunciou o Parcel CSS em 2021, um analisador, transformador, bundler e minificador CSS escrito do zero em Rust. O argumento era velocidade (10-100× mais rápido que os incumbentes baseados em JS) mais correcção (um analisador real seguindo a spec CSS, não pattern-matching por regex) mais compilação targets-aware (reduzir CSS moderno para o que os navegadores mais antigos compreendem, como Babel para JavaScript). Em 2022 o projecto foi renomeado para Lightning CSS para o dissociar do Parcel como ferramenta autónoma. É agora o pipeline CSS moderno recomendado do Vite, o padrão no próprio Parcel e uma opção no css-minimizer-webpack-plugin. O motor de próxima geração Oxide do Tailwind integra-o.

O pipeline CSS moderno

Os projectos web modernos raramente escrevem CSS cru directamente numa folha de estilo. Sass (Hampton Catlin e Natalie Weizenbaum, primeiro lançamento em 2006), Less (Alexis Sellier, 2009) e Stylus (TJ Holowaychuk, 2010) ficam à frente do pipeline, adicionando variáveis, aninhamento, mixins, funções e partials. O compilador emite CSS vanilla, que então flui através do PostCSS para transformações como Autoprefixer (aplicação de prefixos de fornecedor com base em Browserslist), desempacotamento de CSS aninhado e redução de nível de CSS moderno. Só após tudo isto é que o minificador corre, sobre o CSS aplanado final. Os bundlers modernos entregam minificação CSS por defeito, o webpack 5 inclui css-minimizer-webpack-plugin (cssnano por baixo do capot por defeito, com cssoMinify, cleanCssMinify, esbuildMinify e lightningCssMinify todos seleccionáveis); o Vite usa esbuild para CSS por defeito e suporta Lightning CSS como opt-in; o Parcel usa Lightning CSS; Next.js, Remix, Astro, SvelteKit e Nuxt empacotam todos minificação em builds de produção sem intervenção do programador. O resultado é que para qualquer um que use um pipeline de build moderno, a minificação CSS acontece automaticamente.

Mas nem todos usam um pipeline de build. Imensos sites WordPress, páginas HTML escritas à mão, sites estáticos Jekyll/Hugo/Eleventy sem toolchain JS, e projectos pontuais entregam CSS que nunca esteve perto do webpack. Para esses, um minificador no navegador é o caminho de menor resistência, cole o CSS, copie o resultado, guarde o deployment.

Critical CSS

Uma técnica complementar que vale a pena conhecer: critical CSS é a prática de identificar o subconjunto de estilos necessários para renderizar a viewport acima da dobra, fazer inline desse subconjunto directamente num bloco <style> no cabeçalho do documento, e adiar o resto da folha de estilo para um carregamento não-bloqueador. Bem feita, a página pinta a sua viewport inicial na primeiríssima ida e volta de rede, sem qualquer pedido separado para uma folha de estilo externa. A Filament Group construiu a ferramenta canónica, Scott Jehl publicou loadCSS a 14 de Julho de 2014, um pequeno utilitário JavaScript que carrega uma folha de estilo de forma assíncrona definindo o seu atributo media para um valor que não corresponde, e depois alternando-o de volta para all assim que o ficheiro é descarregado. O padrão tornou-se eventualmente padrão suficiente para que os navegadores acrescentassem <link rel="preload" as="style" onload="this.rel='stylesheet'"> como forma mais directa de o exprimir. Jason Miller (criador do Preact) lançou o Critters sob a GoogleChromeLabs em 2018 como alternativa mais rápida, em vez de correr um navegador headless para inspeccionar a página renderizada, o Critters faz análise estática. O repositório Critters foi arquivado em 2024, com o fork activamente mantido a viver agora como Beasties sob a equipa Nuxt. Todas estas ferramentas dependem do CSS subjacente estar bem minificado, cada byte poupado na folha de estilo de origem flui para um inline crítico mais pequeno.

Os hacks de legado desapareceram

Os navegadores modernos analisam todos o CSS segundo a mesma spec. Os hacks históricos que antes tornavam a minificação CSS arriscada essencialmente desapareceram: o hack * html visava o IE6 explorando um bug do analisador; o hack do underscore _property: value visava o IE6 e anteriores; *property: value (com * antes do nome da propriedade) visava o IE7 e anteriores; comentários condicionais <!--[if IE 6]> permitiam servir folhas de estilo diferentes a versões específicas do IE, mas a Microsoft removeu esta funcionalidade no IE10. O IE11 atingiu o seu fim de vida a 15 de Junho de 2022 para a maioria das versões de consumo do Windows 10. A partir de 2026 estes hacks são curiosidades históricas e um minificador CSS já não precisa de pensar neles. Um minificador moderno que retira espaço em branco de forma idêntica entre navegadores e aplica as transformações definidas na spec descritas acima é seguro.

O que esta ferramenta faz (e não faz)

Esta ferramenta é um minificador no navegador num único ficheiro, cerca de 30 linhas de JavaScript. Tokeniza literais de cadeia em placeholders para que as passagens subsequentes não possam corromper o seu conteúdo, remove comentários /* ... */, colapsa espaços em branco à volta de {, }, :, ;, ,, >, ~, +, remove o ponto-e-vírgula final antes de }, colapsa sequências de espaço em branco a um único espaço, encurta cores hex de seis dígitos para a forma de três dígitos quando cada par de dígitos é idêntico, e retira a unidade dos valores zero para px, em, rem, %, pt, ex, ch, vw, vh, vmin, vmax. Não analisa o CSS para um AST, é uma passagem por regex. Não colapsa longhand para shorthand. Não funde nem desduplica selectores. Não reordena declarações. Não converte rgb() para hex nem cores nomeadas para hex. Não passa palavras-chave a minúsculas. Não preserva comentários «importantes» /*!: todos os comentários são removidos por igual; se tiver cabeçalhos de licença a manter, cole-os de volta após a minificação. Não emite source map. O enquadramento honesto: cole o CSS que saiu do seu editor ou da sua mão, receba uma versão despida que é tipicamente 20-40 % mais pequena em bytes brutos, e use-a como artefacto de deployment rápido para sites construídos à mão. Para projectos com um pipeline de build, use cssnano ou Lightning CSS nesse pipeline; para os que não têm, esta ferramenta retira a fricção.

Porque é que só-navegador importa aqui

Cada minificador CSS baseado na web tem a mesma escolha arquitectónica: fazer o trabalho num servidor, ou fazê-lo no navegador do utilizador. O processamento do lado do servidor exige carregar a folha de estilo pela rede, o que significa que uma cópia desse CSS fica nos logs do servidor, possivelmente numa cache de CDN, possivelmente num pipeline de analítica, possivelmente num backup. Para a maior parte do CSS isso é inofensivo. Para ferramentas internas, estilos de produtos não publicados, ou folhas de estilo que contenham selectores revelando taxonomias internas de classes (.admin-panel-internal-debug-info), não é. Mesmo para CSS de site de marketing comum, um programador a auditar o que realmente envia pela rede pode razoavelmente preferir que o trabalho em curso fique na sua máquina. Um minificador puramente baseado no navegador (JavaScript que corre no seu separador e nunca faz um pedido de rede após o carregamento inicial da página) contorna a questão. Pode verificá-lo: abra o separador Network das DevTools, cole o CSS, clique em Minificar e procure qualquer pedido de saída. Não haverá nenhum. Melhor ainda, desligue-se da internet (ou active o modo avião) após o carregamento da página e a ferramenta continuará a funcionar, o que é a prova empírica mais forte de que nada está a ser carregado.

Perguntas frequentes

Quanto vai o meu CSS reduzir?

CSS formatado à mão com comentários e indentação encolhe tipicamente 20-40 % em bytes brutos. CSS que já foi compilado a partir de Sass/Less e ligeiramente formatado encolhe menos. CSS que foi processado através de PostCSS ou Autoprefixer já tem frequentemente comentários mínimos e encolhe menos. O tamanho após compressão Brotli na borda do CDN apertará ainda mais, Brotli sobre CSS minificado ainda poupa mais 5-15 % do que Brotli sobre CSS não minificado, consoante o quão repetitivo era o espaço em branco original.

A saída minificada vai partir alguma coisa?

Para CSS comum, não, as transformações são spec-seguras. Os dois casos que vale a pena verificar você mesmo: (1) valores zero dentro de calc(), min(), max(), clamp() e propriedades CSS personalizadas não devem ser unit-stripped porque as regras de aritmética tipada exigem uma unidade; a passagem regex desta ferramenta é conservadora, mas se tiver calc(0px + 10%) no seu CSS, dê uma vista de olhos à saída. (2) Se a sua folha de estilo tiver fallbacks de propriedades duplicadas como display: flex; display: grid;, esta ferramenta preserva ambos, mas minificadores avançados como o cssnano com o preset advanced removeriam o primeiro. Se depender de comportamento de cascata específico do navegador, audite antes de fazer deploy.

Preserva os cabeçalhos de licença?

Não. Os minificadores de produção respeitam a convenção de que comentários começando por /*! (com ponto de exclamação) são preservados como «importantes», habitualmente para cabeçalhos de copyright e avisos de licença. Esta ferramenta retira todos os comentários por igual. Se entregar CSS que precisa de um cabeçalho de licença (MIT, GPL, atribuição de fonte BSD), cole o cabeçalho manualmente de volta na saída. Para um pipeline que precise de preservação automática, use cssnano ou Lightning CSS.

Devo usá-la se já tenho um pipeline de build?

Provavelmente não, o seu bundler está a fazer isto por si. O webpack 5 entrega css-minimizer-webpack-plugin com cssnano por baixo do capot; o Vite usa esbuild para minificação CSS por defeito; o Parcel usa Lightning CSS. Esta ferramenta é para os casos que o seu pipeline de build não cobre: HTML escrito à mão, temas WordPress entregues sem toolchain Node, geradores de sites estáticos que não empacotam minificação, ficheiros CSS pontuais para um template de email ou uma demo rápida. Para esses, uma ferramenta paste-in no navegador é o caminho de menor resistência.

Os meus ficheiros são carregados?

Não. O minificador é JavaScript a correr no seu navegador. O CSS que cola nunca atravessa a rede, verifique no separador Network das DevTools enquanto clica em Minificar, ou ponha a página offline depois de carregar e confirme que a ferramenta ainda funciona. As folhas de estilo internas, os estilos de produtos não publicados e o CSS revelando taxonomias internas de classes ficam no seu dispositivo.

Posso desminificar a saída mais tarde?

Não exactamente, comentários e espaço em branco originais foram-se para sempre, é esse o objectivo. Mas pode formatar CSS minificado para o tornar legível novamente. Pretty-printers como o Prettier (com o plugin CSS), o comando integrado Format Document do VS Code, ou qualquer das ferramentas online «beautifier CSS» reinserirão indentação e quebras de linha. Não conseguem recuperar comentários eliminados. Mantenha sempre a sua fonte não-minificada no controlo de versão como forma canónica.

Ferramentas relacionadas