Web Performance Engine
by @1kalin
Performs comprehensive web performance audits, diagnoses bottlenecks, and provides targeted fixes for server, rendering, hero element, JavaScript, and layout...
clawhub install afrexai-web-performance-engineπ About This Skill
Web Performance Engine
Complete web performance optimization system. Audit, diagnose, fix, and monitor β no external tools required (but integrates with Lighthouse, WebPageTest, Chrome DevTools when available).
Phase 1: Performance Audit
Quick Health Check
Run these checks in order. Stop when you find the bottleneck tier.
Tier 1 β Critical (blocks rendering):
Tier 2 β Important (affects experience):
Tier 3 β Polish (competitive edge):
Audit Brief Template
audit:
url: ""
device: "mobile" # mobile | desktop | both
connection: "4G" # 3G | 4G | fiber
region: "" # closest to target users
scores:
performance: null # 0-100
fcp_ms: null
lcp_ms: null
tbt_ms: null
cls: null
inp_ms: null
ttfb_ms: null
page_weight:
total_kb: null
html_kb: null
css_kb: null
js_kb: null
images_kb: null
fonts_kb: null
other_kb: null
requests:
total: null
by_type: {}
third_party_count: null
third_party_kb: null
Getting Metrics Without Tools
If no Lighthouse/DevTools available, use web-based tools:
1. web_fetch "https://pagespeed.web.dev/analysis?url={encoded_url}" β Google's free tool
2. web_search "webpagetest {url}" β find cached results
3. web_search "site:{domain} core web vitals" β find CrUX data
4. Check for obvious issues: render-blocking CSS/JS, missing preloads, no meta viewport
Phase 2: Diagnosis β The Performance Waterfall
Critical Rendering Path Analysis
DNS β TCP β TLS β TTFB β HTML Parse β CSSOM β Render Tree β FCP β LCP
β
JS Download β Parse β Execute β INP
Bottleneck Decision Tree:
High TTFB (>800ms)?
ββ YES β Phase 3A: Server optimization
ββ NO β High FCP (>1.8s)?
ββ YES β Phase 3B: Render-blocking resources
ββ NO β High LCP (>2.5s)?
ββ YES β Phase 3C: Hero element optimization
ββ NO β High TBT (>200ms)?
ββ YES β Phase 3D: JavaScript optimization
ββ NO β High CLS (>0.1)?
ββ YES β Phase 3E: Layout stability
ββ NO β High INP (>200ms)?
ββ YES β Phase 3F: Interaction optimization
ββ NO β β
Performance is good!
Resource Impact Scoring
Rate each resource by impact:
| Factor | Weight | Score 1 | Score 3 | Score 5 | |--------|--------|---------|---------|---------| | Size (KB) | 3x | <10 | 10-100 | >100 | | Render-blocking | 5x | No | Partial | Full | | Above-fold impact | 4x | None | Indirect | Direct | | Cacheable | 2x | Long cache | Short cache | No cache | | Compressible | 2x | Already done | Possible | Not compressed |
Priority = Sum(Factor Γ Weight). Fix highest scores first.
Phase 3: Fix Playbooks
3A: Server Optimization (TTFB)
Quick wins:
# CDN: If no CDN, this is #1 priority
Check: curl -sI {url} | grep -i 'x-cache\|cf-cache\|x-cdn'
Compression: Must have brotli or gzip
Check: curl -sI -H "Accept-Encoding: br,gzip" {url} | grep -i content-encoding
HTTP/2 or HTTP/3
Check: curl -sI --http2 {url} | head -1
Server-side checklist:
Cache headers template:
# Static assets (CSS, JS, images, fonts)
Cache-Control: public, max-age=31536000, immutableHTML pages
Cache-Control: public, max-age=0, must-revalidateAPI responses
Cache-Control: private, max-age=60, stale-while-revalidate=300
3B: Render-Blocking Resources (FCP)
CSS optimization:
Rules:
@import (creates sequential loading)JavaScript optimization:
Rules:
defer for app scripts (maintains order, runs after parse)async for independent scripts (analytics, ads) in without defer/async3C: Hero Element Optimization (LCP)
LCP element types and fixes:
| LCP Element | Fix |
|------------|-----|
| | Preload + responsive + modern format |
| poster | Preload poster image |
| CSS background-image | Preload + inline critical CSS |
| Text block | Preload font + font-display: optional |
Image optimization checklist:
Image format decision:
Photo/complex image? β WebP (25-35% smaller than JPEG)
β AVIF (50% smaller, but slower encode)
Simple graphic/logo? β SVG (scalable, tiny)
β PNG only if transparency needed
Animation? β WebM/MP4 video (not GIF β 90% smaller)
Image size targets: | Viewport | Max width | Target KB | |----------|-----------|-----------| | Mobile | 400px | < 50KB | | Tablet | 800px | < 100KB | | Desktop | 1200px | < 150KB | | Hero/banner | 1600px | < 200KB |
3D: JavaScript Optimization (TBT)
Bundle analysis approach:
1. Check total JS size: web_fetch the page, count tags
2. Identify large libraries (React, Lodash, Moment.js)
3. Check for duplicate code across bundles
4. Identify unused exports
Common JS bloat and replacements:
| Library | Size | Alternative | Size | |---------|------|-------------|------| | moment.js | 67KB | date-fns | 2-10KB | | lodash (full) | 71KB | lodash-es (tree-shake) | 2-5KB | | jQuery | 87KB | vanilla JS | 0KB | | animate.css | 80KB | CSS animations | 1-2KB | | chart.js | 60KB | lightweight-charts | 40KB |
Code splitting rules:
const Chart = lazy(() => import('./Chart'))Long task breaking:
// BEFORE: Blocks main thread 200ms+
function processLargeList(items) {
items.forEach(item => heavyComputation(item));
}// AFTER: Yields to main thread
async function processLargeList(items) {
for (const item of items) {
heavyComputation(item);
// Yield every 50ms
if (performance.now() - start > 50) {
await scheduler.yield(); // or setTimeout(0)
start = performance.now();
}
}
}
3E: Layout Stability (CLS)
Top CLS causes and fixes:
| Cause | Fix |
|-------|-----|
| Images without dimensions | Always set width + height |
| Ads/embeds without space | Reserve space with aspect-ratio or min-height |
| Dynamic content injection | Use CSS contain or reserved space |
| Web fonts causing reflow | font-display: optional or swap with size-adjust |
| Late-loading CSS | Inline critical CSS |
Anti-CLS patterns:
/* Reserve space for dynamic content */
.ad-slot { min-height: 250px; }
.embed-container { aspect-ratio: 16/9; }/* Prevent font swap reflow */
@font-face {
font-family: 'Brand';
src: url('brand.woff2') format('woff2');
font-display: optional; /* No swap = no shift */
size-adjust: 105%; /* Match fallback metrics */
}
/* Contain layout shifts */
.dynamic-widget {
contain: layout;
min-height: 200px;
}
3F: Interaction Optimization (INP)
Event handler rules:
requestAnimationFrame for visual updatescontent-visibility: auto for off-screen contentInput responsiveness:
// BEFORE: Blocks during type
input.addEventListener('input', (e) => {
expensiveFilter(e.target.value); // 100ms+
});// AFTER: Debounced + visual feedback
input.addEventListener('input', (e) => {
showSpinner(); // Instant visual feedback
debounce(() => expensiveFilter(e.target.value), 150);
});
Phase 4: Resource Loading Strategy
Preload / Prefetch / Preconnect Decision
Rules:
Lazy Loading Strategy
Above fold (viewport): fetchpriority="high", no lazy
Below fold (1-2 screens): loading="lazy", decoding="async"
Way below fold: Intersection Observer, load on demand
Off-screen widgets: content-visibility: auto
Font Loading Optimization
/* Optimal font loading */
@font-face {
font-family: 'Brand';
src: url('brand.woff2') format('woff2');
font-display: swap;
unicode-range: U+0000-00FF; /* Latin only if applicable */
}
Font checklist:
System font stacks:
/* Modern system fonts β zero network cost */
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;/* Monospace */
font-family: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, monospace;
Phase 5: Third-Party Script Management
Impact Assessment
third_party_audit:
- script: "Google Analytics 4"
size_kb: 45
blocks_render: false
loads_more_scripts: true
total_impact_kb: 90
essential: true
mitigation: "gtag async, delay until interaction"
- script: "Intercom chat widget"
size_kb: 200
blocks_render: false
loads_more_scripts: true
total_impact_kb: 450
essential: false
mitigation: "Load on scroll/click, not page load"
Third-party loading strategies:
// Strategy 1: Load on interaction
document.addEventListener('scroll', () => {
loadThirdParty('chat-widget.js');
}, { once: true });// Strategy 2: Load after page is idle
requestIdleCallback(() => {
loadThirdParty('analytics.js');
});
// Strategy 3: Facade pattern (show placeholder until needed)
chatButton.addEventListener('click', () => {
loadThirdParty('intercom.js').then(() => Intercom('show'));
});
Rules:
rel="noopener" on all external linksPhase 6: Mobile Performance
Mobile-Specific Optimization
Targets (mobile on 4G): | Metric | Good | Needs Work | Poor | |--------|------|------------|------| | FCP | < 1.8s | 1.8-3.0s | > 3.0s | | LCP | < 2.5s | 2.5-4.0s | > 4.0s | | TBT | < 200ms | 200-600ms | > 600ms | | CLS | < 0.1 | 0.1-0.25 | > 0.25 | | INP | < 200ms | 200-500ms | > 500ms |
Mobile-specific checklist:
Phase 7: Performance Budget
Setting Budgets
performance_budget:
metrics:
lcp_ms: 2500
fcp_ms: 1800
tbt_ms: 200
cls: 0.1
inp_ms: 200
resources:
total_kb: 1500
js_kb: 350
css_kb: 80
images_kb: 800
fonts_kb: 100
requests:
total: 60
third_party: 15
lighthouse:
performance: 90
accessibility: 90
best_practices: 90
seo: 90
Budget enforcement rules:
Budget Monitoring Template
# Weekly performance check
date: "YYYY-MM-DD"
url: ""
device: "mobile"scores:
lighthouse: null
lcp: null
fcp: null
tbt: null
cls: null
trend: "improving | stable | degrading"
regressions: []
actions: []
Phase 8: Performance Scoring Rubric
Rate the site 0-100:
| Dimension | Weight | 0-2 | 3-4 | 5 | |-----------|--------|-----|-----|---| | Core Web Vitals | 25% | All red | Mixed | All green | | Page weight | 15% | >5MB | 2-5MB | <2MB | | Caching strategy | 15% | None | Partial | Full with immutable | | Render path | 15% | Multiple blockers | Some optimized | Clean critical path | | Image optimization | 10% | Unoptimized | Partially | WebP/AVIF + responsive | | JavaScript health | 10% | >1MB, no splitting | Some splitting | <350KB, code-split | | Third-party control | 5% | Unmanaged | Some deferred | All managed + budgeted | | Mobile experience | 5% | Desktop-only | Responsive | Mobile-first optimized |
Score interpretation:
Phase 9: Common Architectures β Quick Wins
Next.js / React
next/image (auto WebP, lazy, blur placeholder)dynamic() for heavy components@next/bundle-analyzerWordPress
SPA (React/Vue/Svelte)
Static Sites
Phase 10: Advanced Techniques
Service Worker Caching
// Cache-first for static assets
self.addEventListener('fetch', (event) => {
if (event.request.url.match(/\.(css|js|woff2|webp|avif)$/)) {
event.respondWith(
caches.match(event.request).then(cached => cached || fetch(event.request))
);
}
});
Resource Hints for Navigation
// Predictive prefetch on hover
document.querySelectorAll('a').forEach(link => {
link.addEventListener('mouseenter', () => {
const prefetch = document.createElement('link');
prefetch.rel = 'prefetch';
prefetch.href = link.href;
document.head.appendChild(prefetch);
}, { once: true });
});
Performance Monitoring in Production
// Report Core Web Vitals
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// Send to analytics
sendToAnalytics({
metric: entry.name,
value: entry.value,
rating: entry.rating, // "good" | "needs-improvement" | "poor"
});
}
}).observe({ type: 'largest-contentful-paint', buffered: true });
Edge Cases
Infinite scroll / pagination:
content-visibility: auto for off-screen itemsSPAs with client-side routing:
E-commerce product pages:
Media-heavy sites:
not GIF (90% smaller)