From web-performance-web-performance
Bundle optimization, render performance, Core Web Vitals
How this skill is triggered — by the user, by Claude, or both
Slash command
/web-performance-web-performance:web-performance-web-performanceThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **Quick Guide:** Bundle budgets: < 200KB main bundle gzipped. Core Web Vitals: LCP < 2.5s, INP < 200ms, CLS < 0.1. Profile before optimizing -- measure actual bottlenecks, don't guess. Lazy load routes and heavy libraries. Use React Compiler (React 19+) for automatic memoization; manual memo only when profiling proves a bottleneck. Monitor real users with web-vitals library, not just Lighthouse.
Quick Guide: Bundle budgets: < 200KB main bundle gzipped. Core Web Vitals: LCP < 2.5s, INP < 200ms, CLS < 0.1. Profile before optimizing -- measure actual bottlenecks, don't guess. Lazy load routes and heavy libraries. Use React Compiler (React 19+) for automatic memoization; manual memo only when profiling proves a bottleneck. Monitor real users with web-vitals library, not just Lighthouse.
<critical_requirements>
(You MUST profile BEFORE optimizing - measure actual bottlenecks with browser DevTools, framework profiler, or Lighthouse)
(You MUST set performance budgets BEFORE building features - bundle size limits and Core Web Vitals targets)
(You MUST use named constants for ALL performance thresholds - no magic numbers like 200 or 2.5)
(You MUST monitor Core Web Vitals in production - track LCP, INP, CLS for real users, not just lab metrics)
(You MUST lazy load route components and heavy libraries - code splitting prevents large initial bundles)
</critical_requirements>
Auto-detection: Core Web Vitals, bundle size optimization, LCP, INP, CLS, lazy loading, code splitting, memoization, React Compiler, performance monitoring, web-vitals library, bundle budget, virtualization, react-window, TanStack Virtual
When to use:
When NOT to use:
Key patterns covered:
Detailed Resources:
Performance is a feature, not an afterthought. Fast applications improve user experience, conversion rates, and SEO rankings. Performance optimization requires measurement before action, budgets before building, and monitoring in production.
Core principles:
Set and enforce bundle size limits to prevent bloat. Main bundle should be < 200KB gzipped for fast downloads on 3G networks.
// constants/bundle-budgets.ts
export const BUNDLE_SIZE_BUDGETS_KB = {
MAIN_BUNDLE_GZIPPED: 200,
VENDOR_BUNDLE_GZIPPED: 150,
ROUTE_BUNDLE_GZIPPED: 100,
TOTAL_INITIAL_LOAD_GZIPPED: 500,
MAIN_CSS_GZIPPED: 50,
CRITICAL_CSS_INLINE: 14, // Fits in first TCP packet
} as const;
Why these limits: 200 KB ≈ 1 second download on 3G, faster Time to Interactive (TTI), better mobile performance
Recommended budgets:
For enforcement examples, see examples/code-splitting.md.
Optimize for Google's Core Web Vitals: LCP < 2.5s, INP < 200ms, CLS < 0.1. These metrics impact SEO and user experience.
// constants/web-vitals.ts
export const CORE_WEB_VITALS_THRESHOLDS = {
LCP_SECONDS: 2.5, // Largest Contentful Paint
INP_MS: 200, // Interaction to Next Paint
CLS_SCORE: 0.1, // Cumulative Layout Shift
FCP_SECONDS: 1.8, // First Contentful Paint
TTI_SECONDS: 3.8, // Time to Interactive
TBT_MS: 300, // Total Blocking Time
TTFB_MS: 800, // Time to First Byte
} as const;
Measures loading performance -- when the largest visible element renders.
How to improve: Optimize images (modern formats, preload hero images), minimize render-blocking resources, use CDN for static assets, SSR or SSG for critical content.
Measures interactivity across ALL user interactions (replaced FID in March 2024). Includes input delay, processing time, and presentation delay.
How to improve: Minimize JavaScript execution time, code split to load less JS upfront, use web workers for heavy computation, break up long tasks (> 50ms) with scheduler.yield() or setTimeout.
Measures visual stability -- prevents unexpected layout shifts.
How to improve: Set explicit image/video dimensions, reserve space for dynamic content (ads, embeds), avoid injecting content above existing content, use font-display: swap with size-adjust.
For detailed examples and monitoring setup, see examples/web-vitals.md.
Lazy load route components and heavy libraries. Code splitting keeps the initial bundle small by loading code on demand.
import { lazy, Suspense } from 'react';
// Route-based splitting - each route is a separate chunk
const Dashboard = lazy(() => import('./pages/dashboard'));
const Reports = lazy(() => import('./pages/reports'));
export function App() {
return (
<Suspense fallback={<PageLoader />}>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/reports" element={<Reports />} />
</Routes>
</Suspense>
);
}
Why good: Splits bundle by route, loads components on demand, users only download what they navigate to
When to lazy load: Route components, heavy feature modules, modals/dialogs, below-fold content
When NOT to lazy load: Above-fold components, error boundaries, loading states
For tree shaking and bundle enforcement, see examples/code-splitting.md.
Profile before memoizing. React Compiler (v1.0, Oct 2025) auto-memoizes in most cases. Manual memo only when profiling proves a bottleneck.
// Only memoize when profiling shows > 5ms render time
const EXPENSIVE_RENDER_MS = 5;
// ✅ Expensive calculation with large dataset
const sortedRows = useMemo(
() => [...rows].sort((a, b) => compareValues(a[sortColumn], b[sortColumn])),
[rows, sortColumn],
);
// ❌ Trivial calculation - memo overhead exceeds cost
const doubled = useMemo(() => value * 2, [value]);
React Compiler (React 19+): Automatically memoizes components, values, and functions at build time. Manual useMemo/useCallback/React.memo rarely needed. Only add manual memo for: third-party interop, non-pure computations, or when profiling shows the compiler missed an optimization.
For complete memoization patterns, see examples/core.md.
<red_flags>
High Priority Issues:
import _ from 'lodash') -- bundles unused code, prevents tree shakingMedium Priority Issues:
require()) -- prevents tree shakingGotchas & Edge Cases:
React.memo uses shallow comparison -- deep object props always trigger re-renderuseMemo/useCallback have overhead -- only use for expensive operations (> 5ms)</red_flags>
<critical_reminders>
(You MUST profile BEFORE optimizing - measure actual bottlenecks with browser DevTools, framework profiler, or Lighthouse)
(You MUST set performance budgets BEFORE building features - bundle size limits and Core Web Vitals targets)
(You MUST use named constants for ALL performance thresholds - no magic numbers like 200 or 2.5)
(You MUST monitor Core Web Vitals in production - track LCP, INP, CLS for real users, not just lab metrics)
(You MUST lazy load route components and heavy libraries - code splitting prevents large initial bundles)
Failure to follow these rules will result in slow applications, poor Core Web Vitals, large bundles, and degraded user experience.
</critical_reminders>
npx claudepluginhub agents-inc/skills --plugin web-performance-web-performanceOptimizes web performance with bundle analysis, code splitting, image optimization, caching headers, and virtual lists. Useful for improving Core Web Vitals and load times.
Optimizes frontend performance through Core Web Vitals fixes, bundle analysis and code splitting, lazy loading, tree shaking, and image optimization. Use for improving page speed and load times.
Optimizes web app performance using React code splitting, webpack bundles, image optimization, service workers, caching, and Core Web Vitals monitoring for faster loads and better metrics.