performance-analyzer
SKILL.md
Performance Analyzer Skill
This skill analyzes CSS performance and identifies optimization opportunities. I'll examine bundle size, selector efficiency, render performance, and suggest specific improvements to make your CSS faster.
What I Analyze
Bundle Analysis
- Total CSS file size
- Unused CSS percentage
- Duplicate rules
- Minification potential
- Compression ratios
Selector Performance
- Selector complexity
- Expensive selectors
- Over-specific rules
- Selector matching speed
Render Performance
- Render-blocking CSS
- Critical CSS opportunities
- Paint/layout triggers
- Animation performance
Loading Strategy
- CSS delivery method
- Code splitting potential
- Async loading opportunities
- Caching strategy
Performance Metrics
Key Indicators
First Contentful Paint (FCP)
- When first content appears
- Target: < 1.8s
Largest Contentful Paint (LCP)
- When main content visible
- Target: < 2.5s
Cumulative Layout Shift (CLS)
- Visual stability
- Target: < 0.1
CSS Bundle Size
- Total downloaded CSS
- Target: < 50KB gzipped for initial load
Unused CSS
- Percentage not used on page
- Target: < 20% unused
Bundle Size Analysis
File Size Audit
# Check CSS file sizes
ls -lh dist/*.css
# Example output:
# styles.css 250KB (uncompressed)
# styles.min.css 180KB (minified)
# styles.min.css.gz 45KB (gzipped)
Optimization Potential
Original: 250KB (100%)
Minified: 180KB (72%) - Remove whitespace, comments
Gzipped: 45KB (18%) - Compression
Unused removed: 30KB (12%) - Remove unused CSS
Optimized: 30KB (12%) - Final target
Potential savings: 88%
Bundle Composition
Analyze what's in your bundle:
Vendor CSS (Bootstrap, etc.): 120KB (48%)
Component styles: 80KB (32%)
Utility classes: 30KB (12%)
Global styles: 20KB (8%)
Recommendations:
1. Remove unused Bootstrap components
2. Use PurgeCSS for utilities
3. Split vendor from custom CSS
Selector Performance
Expensive Selectors
/* ❌ VERY SLOW - Universal selector with pseudo */
*:hover {
cursor: pointer;
}
/* ❌ SLOW - Descendant with universal */
.container * {
box-sizing: border-box;
}
/* ❌ SLOW - Complex attribute selectors */
[class^="icon-"][class$="-large"] {
font-size: 2rem;
}
/* ❌ SLOW - Deep nesting */
.nav ul li a span.icon {
color: blue;
}
/* ✓ FAST - Single class */
.icon-large {
font-size: 2rem;
}
/* ✓ FAST - Low specificity */
.nav-icon {
color: blue;
}
Selector Complexity Scoring
Complexity Score (Lower is better):
Single class: 1 point (.button)
Element selector: 1 point (div)
Class + element: 2 points (div.button)
Descendant: +1 per level (.nav .item .link = 3)
Pseudo-class: +1 (:hover)
Attribute: +2 ([type="text"])
Complex attribute: +3 ([class*="btn-"])
Universal: +5 (*)
Target: Average < 5 points per selector
Refactoring Examples
/* BEFORE: Complexity 8 */
.container .sidebar nav ul li a:hover {
color: blue;
}
/* Score: 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 = 8 */
/* AFTER: Complexity 2 */
.sidebar-link:hover {
color: blue;
}
/* Score: 1 + 1 = 2 */
/* BEFORE: Complexity 10 */
div[class^="card-"][class$="-featured"]:not(.disabled) {
border: 2px solid gold;
}
/* Score: 1 + 3 + 3 + 2 + 1 = 10 */
/* AFTER: Complexity 1 */
.card--featured {
border: 2px solid gold;
}
/* Score: 1 */
Render Performance
Properties That Trigger Reflow (Layout)
/* ❌ EXPENSIVE - Triggers layout recalculation */
.animated {
animation: move 1s;
}
@keyframes move {
from { left: 0; width: 100px; }
to { left: 100px; width: 200px; }
}
/* These properties trigger layout:
* width, height, padding, margin, border
* top, right, bottom, left
* font-size, line-height
* display, position, float
*/
Properties That Trigger Paint
/* ⚠️ MODERATE - Triggers repaint */
.animated {
animation: fade 1s;
}
@keyframes fade {
from { background: red; }
to { background: blue; }
}
/* These properties trigger paint:
* color, background, box-shadow
* border-radius, border-style
* visibility, outline
*/
Compositor-Only Properties (FAST)
/* ✓ OPTIMAL - GPU accelerated */
.animated {
animation: slide 1s;
}
@keyframes slide {
from { transform: translateX(0); opacity: 0; }
to { transform: translateX(100px); opacity: 1; }
}
/* These are compositor-only:
* transform (translate, rotate, scale)
* opacity
*/
Animation Performance Comparison
/* ❌ POOR PERFORMANCE */
@keyframes slideIn {
from { left: -100px; } /* Triggers layout */
to { left: 0; }
}
/* Performance impact:
* - Recalculates layout (expensive)
* - Repaints (expensive)
* - Composites (cheap)
* Total: ~50ms per frame
* Result: Janky animation < 60fps
*/
/* ✓ GOOD PERFORMANCE */
@keyframes slideIn {
from { transform: translateX(-100px); } /* Compositor only */
to { transform: translateX(0); }
}
/* Performance impact:
* - Composites (cheap)
* Total: ~1-2ms per frame
* Result: Smooth animation @ 60fps
*/
Critical CSS Strategy
What is Critical CSS?
CSS required for above-the-fold content. Should be inlined in <head> to eliminate render-blocking requests.
Critical CSS Identification
/* CRITICAL - Above the fold */
/* Inline these in <head> */
/* Reset */
*, *::before, *::after {
box-sizing: border-box;
}
body {
margin: 0;
font-family: system-ui;
}
/* Header (visible immediately) */
.header {
display: flex;
padding: 1rem;
background: white;
}
.logo {
font-size: 1.5rem;
}
.nav {
display: flex;
gap: 1rem;
}
/* Hero section (above fold) */
.hero {
min-height: 400px;
padding: 4rem 2rem;
background: #f0f0f0;
}
.hero-title {
font-size: 3rem;
margin: 0;
}
/* NON-CRITICAL - Load async */
/* Footer, modals, below-fold content */
Implementation
<!DOCTYPE html>
<html>
<head>
<!-- INLINE CRITICAL CSS -->
<style>
/* Critical CSS here (< 14KB) */
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font-family: system-ui; }
.header { /* ... */ }
.hero { /* ... */ }
</style>
<!-- PRELOAD FULL STYLESHEET -->
<link rel="preload" href="/styles.css" as="style">
<!-- LOAD FULL STYLESHEET ASYNC -->
<link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'">
<noscript><link rel="stylesheet" href="/styles.css"></noscript>
</head>
<body>
<!-- Content -->
</body>
</html>
CSS Loading Optimization
Loading Strategy Analysis
/* ❌ POOR - Single large bundle, render-blocking */
<link rel="stylesheet" href="/styles.css"> <!-- 250KB -->
/* Issues:
* - Blocks rendering until entire file downloads
* - Contains unused CSS
* - No prioritization
*/
/* ✓ BETTER - Critical CSS inline + async full */
<style>/* Critical CSS */</style>
<link rel="preload" href="/styles.css" as="style">
<link rel="stylesheet" href="/styles.css" media="print" onload="this.media='all'">
/* Benefits:
* - Immediate rendering with critical CSS
* - Non-blocking full stylesheet load
* - Faster FCP
*/
/* ✓ BEST - Critical inline + route-based splitting */
<style>/* Critical CSS */</style>
<link rel="preload" href="/common.css" as="style">
<link rel="preload" href="/page.css" as="style">
<link rel="stylesheet" href="/common.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="/page.css" media="print" onload="this.media='all'">
/* Benefits:
* - Only loads CSS needed for current page
* - Common styles cached across pages
* - Optimal bundle size
*/
HTTP/2 Considerations
<!-- With HTTP/2, can load multiple files efficiently -->
<link rel="stylesheet" href="/reset.css"> <!-- 2KB -->
<link rel="stylesheet" href="/typography.css"> <!-- 5KB -->
<link rel="stylesheet" href="/layout.css"> <!-- 8KB -->
<link rel="stylesheet" href="/components.css"> <!-- 15KB -->
<!-- Advantages:
* Better caching (only changed files re-download)
* Parallel loading
* Selective loading possible
-->
Optimization Tools
Analysis Tools
# CSS Stats - Analyze CSS complexity
npx cssstats styles.css > stats.json
# Coverage - Find unused CSS (Chrome DevTools)
# DevTools → Coverage → Record → Reload
# Lighthouse - Performance audit
lighthouse https://example.com --only-categories=performance
# Bundle analyzer
npx webpack-bundle-analyzer stats.json
Optimization Tools
# Minification - Remove whitespace
npx cssnano styles.css styles.min.css
# PurgeCSS - Remove unused CSS
npx purgecss --css styles.css --content '**/*.html' --output dist/
# Critical - Extract critical CSS
npx critical index.html --base dist --inline > optimized.html
# Compression - Gzip/Brotli
gzip -9 styles.css # Gzip
brotli -q 11 styles.css # Brotli (better)
Performance Budget
Set Targets
# performance-budget.yml
# Bundle sizes
css-total: 50KB # Total CSS (gzipped)
css-critical: 14KB # Inline critical CSS
css-vendor: 20KB # Third-party CSS
# Metrics
first-contentful-paint: 1.8s
largest-contentful-paint: 2.5s
cumulative-layout-shift: 0.1
# Code quality
unused-css: 20% # Max unused CSS
avg-selector-depth: 3 # Max avg nesting
specificity-avg: 30 # Max avg specificity
Monitor & Enforce
# Add to CI/CD pipeline
npm run build
npm run analyze-bundle
# Check if bundle exceeds budget
if [ $(stat -f%z dist/styles.css.gz) -gt 51200 ]; then
echo "❌ CSS bundle exceeds 50KB limit"
exit 1
fi
Performance Checklist
Bundle Size
- Minified CSS (cssnano, clean-css)
- Gzip/Brotli compression enabled
- Unused CSS removed (PurgeCSS)
- Duplicate rules eliminated
- Bundle size < 50KB (gzipped)
Selectors
- Average depth < 3 levels
- No universal selectors in production
- Complex attribute selectors removed
- BEM or similar flat methodology
Rendering
- Animations use transform/opacity only
- No layout-triggering properties in animations
- will-change used appropriately (and removed)
- contain property used where appropriate
Loading
- Critical CSS inlined (< 14KB)
- Non-critical CSS loaded async
- CSS split by route/feature
- HTTP caching configured
Monitoring
- Performance budget set
- Lighthouse CI configured
- Bundle size tracked
- Metrics monitored
Example Analysis Report
Input: Analyze styles.css (250KB)
Report:
# CSS Performance Analysis
## Bundle Size 🔴
- **Uncompressed**: 250KB
- **Minified**: 180KB (28% savings)
- **Gzipped**: 45KB (82% total savings)
- **Status**: ❌ Exceeds 50KB budget
### Recommendations:
1. Remove unused CSS (estimated 70KB savings)
2. Split vendor CSS (Bootstrap) from custom
3. Implement code splitting by route
## Selector Performance ⚠️
- **Average depth**: 4.2 levels
- **Complex selectors**: 23 found
- **Universal selectors**: 5 found
### Top Issues:
1. `.container * { }` - Universal descendant (line 45)
2. `#nav ul li a span` - 5 levels deep (line 234)
3. `[class*="btn-"]:not(.disabled)` - Complex attribute (line 567)
### Recommendations:
1. Refactor to BEM methodology
2. Replace universal selectors with specific classes
3. Flatten deeply nested selectors
## Render Performance ✓
- **Layout-triggering animations**: 2 found
- **Paint-heavy properties**: 15 instances
- **Compositor-only**: 8 animations
### Issues:
1. `@keyframes slideIn` uses `left` property (line 890)
- **Fix**: Use `transform: translateX()`
2. `.animated` animates `width` (line 923)
- **Fix**: Use `transform: scaleX()`
## Critical CSS ⚠️
- **Above-fold CSS**: ~35KB
- **Currently inline**: 0KB
- **Render-blocking**: Yes
### Recommendations:
1. Extract critical CSS (header, hero, navigation)
2. Inline critical CSS (target < 14KB)
3. Load remaining CSS async
## Priority Actions:
1. 🔴 **HIGH**: Remove unused CSS (↓ 70KB)
2. 🟠 **MEDIUM**: Inline critical CSS (improve FCP by ~1s)
3. 🟡 **LOW**: Refactor selectors (improve maintainability)
## Expected Impact:
- Bundle size: 250KB → 50KB (80% reduction)
- FCP: 3.2s → 1.5s (53% improvement)
- LCP: 4.5s → 2.2s (51% improvement)
Just Ask!
Request performance analysis:
- "Analyze this CSS file for performance"
- "Find expensive selectors"
- "Identify critical CSS"
- "Check my animation performance"
- "Suggest bundle optimizations"
I'll provide actionable optimization recommendations!
Weekly Installs
4
Repository
andronics/claud…-css-proFirst Seen
Feb 24, 2026
Security Audits
Installed on
github-copilot4
codex4
kimi-cli4
gemini-cli4
cursor4
opencode4