web-performance-web-performance-eab82a — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited web-performance-web-performance-eab82a (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
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:
<philosophy>
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:
</philosophy>
<patterns>
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;#### LCP (Largest Contentful Paint): < 2.5s
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.
#### INP (Interaction to Next Paint): < 200ms
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.
#### CLS (Cumulative Layout Shift): < 0.1
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.
</patterns>
<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>
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.