Dead CSS Removal Workflow
Created: 2025-11-28
Tools: Lighthouse MCP, CSS MCP, Browser Tools, grep
Overview
Section titled “Overview”Removing unused CSS improves page load performance, reduces bundle size, and makes stylesheets easier to maintain. However, there is no magic button that safely removes CSS automatically—static analysis tools can’t detect dynamically-generated class names (Stimulus, Rails helpers, JavaScript).
This document outlines a safe, methodical workflow using AI-assisted tools available in Cursor.
Why Not Just Use PurgeCSS?
Section titled “Why Not Just Use PurgeCSS?”Tools like PurgeCSS work well for static sites but are risky for Rails applications because:
- Dynamic classes:
class: "btn-#{variant}"in Ruby - Stimulus controllers: Classes added via JavaScript
- Conditional rendering: Classes only used in specific states
- Third-party components: Bootstrap, Font Awesome classes
The workflow below uses targeted analysis instead of aggressive purging.
Phase 1: Identify Unused CSS
Section titled “Phase 1: Identify Unused CSS”Step 1.1: Run Lighthouse Audit
Section titled “Step 1.1: Run Lighthouse Audit”First, identify which CSS files have the most unused code:
Run a Lighthouse performance audit on https://www.warmlyyours.me:3000Focus on the "Reduce unused CSS" opportunityExpected output: File paths, estimated savings, and coverage percentages.
Step 1.2: Get Detailed Coverage Report
Section titled “Step 1.2: Get Detailed Coverage Report”For deeper analysis, use Chrome DevTools Coverage:
Navigate to https://www.warmlyyours.me:3000Take a screenshot showing the page loadedThen manually:
- Open DevTools → Coverage tab (Cmd+Shift+P → “Coverage”)
- Click reload to capture CSS usage
- Look for files with high “Unused Bytes” percentage
Step 1.3: Analyze Specific Stylesheets
Section titled “Step 1.3: Analyze Specific Stylesheets”Once you identify problem files, analyze their complexity:
Analyze the CSS in client/stylesheets/www/03-components/page-blog.scssfor unused patterns and complexity issuesPhase 2: Verify Before Deleting
Section titled “Phase 2: Verify Before Deleting”Step 2.1: Search for Class Usage
Section titled “Step 2.1: Search for Class Usage”Never delete a class without searching the entire codebase first.
Search for the class "hero-wrapper-old" in app/views, app/components,and client/js directories. Is it used anywhere?Or use grep directly:
# Search for a specific classgrep -r "hero-wrapper-old" app/ client/ --include="*.erb" --include="*.rb" --include="*.js" --include="*.scss"
# Search for partial class names (dynamic classes)grep -r "hero-wrapper" app/ client/ --include="*.erb" --include="*.rb"Step 2.2: Check for Dynamic Class Generation
Section titled “Step 2.2: Check for Dynamic Class Generation”Look for patterns that generate classes dynamically:
# Rails helpersclass: "card-#{type}"class_names("active" => condition)
# Stimuluselement.classList.add("loading")this.element.classList.toggle("open")Ask the AI:
Are there any dynamic class patterns in app/helpers or app/javascriptthat might generate classes starting with "hero-"?Step 2.3: Check Bootstrap/Framework Classes
Section titled “Step 2.3: Check Bootstrap/Framework Classes”Before removing a class, verify it’s not from Bootstrap:
Is "d-flex" a Bootstrap utility class? What does it do?Check browser compatibility for the CSS property "gap" in flexboxPhase 3: Safe Removal
Section titled “Phase 3: Safe Removal”Step 3.1: Remove One Class at a Time
Section titled “Step 3.1: Remove One Class at a Time”Don’t batch-delete. Remove classes individually and verify:
Delete the .hero-wrapper-old class from client/stylesheets/www/03-components/hero.scssStep 3.2: Rebuild Assets
Section titled “Step 3.2: Rebuild Assets”After each change:
eval "$(mise activate zsh)" && yarn buildStep 3.3: Visual Regression Check
Section titled “Step 3.3: Visual Regression Check”Take before/after screenshots to catch layout shifts:
Take a screenshot of https://www.warmlyyours.me:3000Compare with the previous state. Look for:
- Missing elements
- Broken layouts
- Shifted content
- Missing hover states
Step 3.4: Test Critical Pages
Section titled “Step 3.4: Test Critical Pages”After removing CSS, audit affected pages:
Run Lighthouse on the homepage, a product page, and the contact formto verify no accessibility or performance regressionPhase 4: Ongoing Maintenance
Section titled “Phase 4: Ongoing Maintenance”4.1: Prevent Dead CSS Accumulation
Section titled “4.1: Prevent Dead CSS Accumulation”- Use component-scoped CSS: Keep styles close to their components
- Document class purpose: Add comments for non-obvious classes
- Review during PRs: Check if new CSS duplicates existing styles
- Regular audits: Run Lighthouse monthly
4.2: Safe Patterns for Dynamic Classes
Section titled “4.2: Safe Patterns for Dynamic Classes”When you need dynamic classes, use allowlists:
// _safelist.scss - Classes that might appear unused but are dynamically generated// Do not remove these without checking JavaScript/Ruby code
// Used by Stimulus controllers.is-loading { }.is-active { }.is-open { }
// Used by Rails helpers.alert-success { }.alert-danger { }.alert-warning { }4.3: Document Removed CSS
Section titled “4.3: Document Removed CSS”Keep a log of what was removed and why:
## CSS Cleanup Log
### 2025-11-28- Removed `.hero-wrapper-old` - replaced by `.hero-container` in refactor- Removed `.legacy-button` - unused since Bootstrap 5 migration- Kept `.card-highlight` - used dynamically in product_card_helper.rbQuick Reference: MCP Commands
Section titled “Quick Reference: MCP Commands”| Task | Prompt |
|---|---|
| Audit performance | Run Lighthouse audit on [URL] |
| Check CSS property | What are the values for CSS [property]? |
| Browser support | Is CSS [feature] supported in Safari? |
| Analyze CSS file | Analyze the CSS in [file] for issues |
| Search codebase | Search for class "[name]" in app/views |
| Take screenshot | Take a screenshot of [URL] |
Example Workflow Session
Section titled “Example Workflow Session”Here’s a complete example of removing dead CSS:
1. Identify Problem
Section titled “1. Identify Problem”Run Lighthouse performance audit on https://www.warmlyyours.me:3000/floor-heatingWhat's the "Reduce unused CSS" recommendation?AI Response: “The page has 45KB of unused CSS, primarily from webpack-bundle.css. Top unused selectors include .legacy-carousel, .old-modal, .deprecated-grid…“
2. Verify Usage
Section titled “2. Verify Usage”Search for "legacy-carousel" in app/views, app/components, and client/js.Is this class used anywhere?AI Response: “No matches found in app/views or app/components. Found 1 match in client/stylesheets/www/03-components/carousel.scss (the definition itself).“
3. Check for Dynamic Usage
Section titled “3. Check for Dynamic Usage”Search for "legacy" or "carousel" patterns in app/helpers that mightgenerate this class dynamicallyAI Response: “No dynamic patterns found that would generate legacy-carousel.”
4. Remove Safely
Section titled “4. Remove Safely”Delete the .legacy-carousel class and its related styles fromclient/stylesheets/www/03-components/carousel.scss5. Rebuild and Verify
Section titled “5. Rebuild and Verify”eval "$(mise activate zsh)" && yarn buildTake a screenshot of https://www.warmlyyours.me:3000/floor-heating6. Final Audit
Section titled “6. Final Audit”Run Lighthouse on the same page. Did the unused CSS decrease?Troubleshooting
Section titled “Troubleshooting””I deleted a class and something broke”
Section titled “”I deleted a class and something broke””git checkout -- [file]to restore the file- Search more broadly:
grep -r "partial-class-name" . - Check JavaScript files for
classList.add()calls - Look for Ruby string interpolation:
"class-#{variable}"
”Lighthouse shows unused CSS but I can’t find it”
Section titled “”Lighthouse shows unused CSS but I can’t find it””- The CSS might be from a vendor library (Bootstrap, Font Awesome)
- The CSS might only be used on other pages
- The CSS might be loaded but apply to elements not on the current page
”The class is used but Lighthouse still flags it”
Section titled “”The class is used but Lighthouse still flags it””This is normal—Lighthouse only analyzes the current page state. A class used on hover, after JavaScript runs, or on different screen sizes may be flagged as “unused” but is actually needed.
Related Documentation
Section titled “Related Documentation”- Asset Build Workflow
- CSS MCP Prompts
- Lighthouse MCP Prompts
- Skills Index