CSS Optimization: Critical CSS and Purge Unused Styles

CSS Optimization: Critical CSS and Purge Unused Styles

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1285
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1240
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    982
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1032
  • image_website-sbh_0.webp
    Website development for SBH Partners
    1104
  • image_website-_0.webp
    Website development for Red Pear
    553

CSS Optimization: Critical CSS and Purge Unused Styles

Slow page load is often caused by excessive CSS. Render-blocking CSS delays the first contentful paint (FCP) and increases Largest Contentful Paint (LCP). Bootstrap out of the box weighs 140 KB, but after removing unused classes, it stays at 5–15 KB (a 96% reduction). Tailwind in development mode is 3.5 MB; after purge — 5–50 KB. We configure critical CSS and purge for any stack: from Laravel to Next.js, achieving FCP < 1 second. Our experience: 7+ years in performance optimization, over 50 projects. The result — passing Core Web Vitals without compromises. In 2–3 days, we implement critical CSS and purge turnkey.

How critical CSS affects Core Web Vitals metrics?

LCP (Largest Contentful Paint) — the rendering time of the largest element on the screen. If CSS loads synchronously (render-blocking), the browser doesn't paint content until full style load. Inline critical CSS eliminates this delay: styles for above-the-fold content are inserted directly into <head>, the rest loads asynchronously.

Example: on a Bootstrap site, only styles for the header, hero, and buttons end up in critical CSS — about 5 KB instead of 140 KB. LCP drops from 4 to 1.5 seconds (a 62% improvement). FCP decreases from 2.5 to 1.2 seconds.

What is purge CSS and how to configure it?

Purge removes classes not found in templates. In Tailwind 3+, purge is built-in via the content config:

// tailwind.config.ts import type { Config } from 'tailwindcss'; export default { content: [ './resources/views/**/*.blade.php', './resources/js/**/*.{ts,tsx}', './resources/js/**/*.json', // if classes are generated dynamically ], theme: { extend: {} }, plugins: [], } satisfies Config; 

Dynamic classes (string concatenation) — purge won't find them:

// Bad — purge will not see const color = 'red'; <div className={`text-${color}-500`} /> // Good — full class names const colorMap = { red: 'text-red-500', blue: 'text-blue-500', }; <div className={colorMap[color]} /> 

What is safelist and why is it needed?

Safelist is a whitelist of classes that purge should not remove. Sometimes classes are added via JavaScript, for example, Bootstrap modals: modal-open, show. If they are not found in HTML templates, purge will remove them — breaking functionality. We configure safelist in PurgeCSS config:

// postcss.config.js import purgecss from '@fullhuman/postcss-purgecss'; export default { plugins: [ purgecss({ content: [ './resources/views/**/*.blade.php', './resources/js/**/*.tsx', './public/**/*.html', ], safelist: { standard: ['modal-open', 'show', 'active', 'fade'], deep: [/^modal/, /^alert/, /^toast/], greedy: [/swiper/], }, defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || [], }), ], }; 

Step-by-step purge CSS configuration

  1. Audit current CSS. Use Coverage in DevTools, bundle analysis, identify render-blocking.
  2. Configure purge. Set up PurgeCSS or Tailwind JIT, specify paths to templates.
  3. Create safelist. Add classes used dynamically (modals, alerts, animations).
  4. Testing. Check that nothing broke, visual regression.
  5. Deploy. Integrate purge into the build (Vite, Webpack, Laravel Mix) and deploy to production.

Choosing a strategy: runtime CSS vs static CSS

CSS-in-JS (styled-components, Emotion) generates styles at runtime — additional JS load. For production, static CSS is preferable.

Parameter CSS-in-JS Static CSS (Tailwind, CSS Modules)
Runtime overhead Yes No
Bundle size +50–150 kB (runtime) 0 kB
Tree-shaking Complex Simple
SSR support Requires setup Out of the box

Static CSS is better for Core Web Vitals: it doesn't block rendering (after critical inline) and loads CPU less.

For Vite, critical CSS is configured via critters:

// vite.config.ts import { defineConfig } from 'vite'; import { critters } from 'critters'; export default defineConfig({ plugins: [ critters({ preload: 'media', pruneSource: true, logLevel: 'silent', }) ] }); 

In Laravel, critical CSS is inserted manually:

<style>{!! file_get_contents(public_path('css/critical.css')) !!}</style> <link rel="preload" href="{{ mix('css/app.css') }}" as="style" onload="this.onload=null;this.rel='stylesheet'"> <noscript> <link rel="stylesheet" href="{{ mix('css/app.css') }}"> </noscript> 

Minification — done by LightningCSS in Vite or cssnano. Output: CSS bundle < 20 KB, coverage > 80%.

Metrics comparison before and after optimization

Metric Before optimization After
CSS size (Bootstrap) 140 KB 5 KB
LCP 4.0 s 1.5 s
FCP 2.5 s 1.2 s
TTFB 0.8 s 0.6 s (unchanged)
Common mistakes in CSS optimization
  • Ignoring dynamic classes — purge removes them, breaking the interface.
  • Incorrect safelist — modals, alerts stop being styled.
  • Critical CSS not updated when content changes.
  • Forgetting about iframes and third-party scripts — their CSS also affects metrics.
  • Over-optimization: removing classes used in non-obvious places (archives, static pages).

What's included in CSS optimization work?

  • Audit of current CSS: Coverage in DevTools, bundle analysis, identification of render-blocking.
  • Purge configuration: PurgeCSS or Tailwind JIT config, safelist creation.
  • Critical CSS extraction: automatically via critters or manually using npx critical.
  • Minification and compression: LightningCSS / esbuild, Gzip / Brotli.
  • Integration into the build: Vite, Webpack, Laravel Mix, Next.js.
  • Metrics check: LCP, FCP, TBT before and after.
  • Documentation: description of settings, recommendations for maintenance.

Result: passing Core Web Vitals, minimal CSS bundle size, preserved functionality and styles.

We use PurgeCSS, Tailwind JIT, critters, and PostHTML depending on the stack. Everything is configured for your build.

Contact us for a detailed audit of your project. Get a consultation on suitable tools. We will assess your CSS in 1 day. Order CSS optimization and speed up your site.