SPB Git

spb/ultra-sharp-agent-skills Public

Ultra-Sharp Agent Skills — a research-first skill-authoring system + 72 production-ready skills for AI agents.

Python 100%
4.2 KB · 66 lines markdown
Rendered Raw Blame History
1---2name: optimizing-web-performance3description: Optimizes web page loading and interactivity against Core Web Vitals budgets — LCP, INP, CLS, JS weight — via image/font optimization, code-splitting, and script loading. Use when the user asks to make a page or site faster, fix Core Web Vitals, improve LCP, INP, CLS, or Lighthouse/PageSpeed scores, reduce bundle size, optimize images or fonts, or diagnose slow page loads. Do not use for animation smoothness or jank during interactions (crafting-ui-animations) or for backend/API latency.4---56<!--7Author: Simon-Pierre Boucher8Contact: contact@spboucher.ai9-->1011# Optimizing Web Performance1213## When to use / when NOT to use14- **Use for:** page-load and interactivity performance — Core Web Vitals, bundle size, images, fonts, script loading, hydration cost.15- **Do NOT use for:** animation frame-rate work (crafting-ui-animations), server/database latency, or React render architecture (building-react-components).1617## Budgets (2026 targets, p75 real-user)1819| Metric | Budget |20|---|---|21| LCP (Largest Contentful Paint) | ≤ 2.5 s |22| INP (Interaction to Next Paint) | ≤ 200 ms |23| CLS (Cumulative Layout Shift) | ≤ 0.1 |24| JavaScript, gzipped, interactive page | ≤ 400 KB |2526## Core rules27281. **Measure before optimizing.** Run Lighthouse (lab) and check real-user data (CrUX / RUM) first; fix the worst failing metric, not the easiest one.29   - ❌ "minify everything" before knowing whether LCP or INP is the problem30312. **The LCP element loads first, eagerly.** Preload the hero image, serve it in AVIF/WebP, and never lazy-load it.32   -`<link rel="preload" as="image" href="hero.avif">` + `<img fetchpriority="high" …>`33   -`<img loading="lazy">` on the hero34353. **Every image ships sized, modern, and responsive.** `width`/`height` attributes (prevents CLS), `srcset`/`sizes` for viewports, `loading="lazy"` below the fold only.36374. **Fonts: self-host, subset, `font-display: swap`, preload the one used above the fold.** Two families maximum; variable font when more than two weights are needed.38395. **Ship less JavaScript.** Code-split by route, `import()` heavy widgets on interaction, prefer server rendering with minimal hydration; audit with a bundle analyzer before adding any dependency over ~10 KB gz.40   -`const Chart = lazy(() => import('./Chart'))` mounted when scrolled into view41   - ❌ charting + date + animation libraries in the entry bundle42436. **Nothing render-blocking, no third-party scripts in the critical path.** `defer` all scripts; load analytics/chat/ads after load or on idle; inline only the critical CSS.44457. **Reserve space for everything that arrives late.** Ads, embeds, banners, and skeletons get fixed dimensions or `aspect-ratio` so nothing shifts (CLS).46478. **Long tasks break INP — chunk them.** Split main-thread work over 50 ms with `scheduler.yield()`/`setTimeout`, debounce input handlers, move pure computation to a Web Worker.4849## Workflow50511. Baseline: run Lighthouse on the target page (mobile, throttled) and record LCP/INP/CLS/JS-weight against the budget table.522. Identify the single worst offender per failing metric (LCP element, longest task, largest shift source, biggest bundle chunk).533. Apply the matching rule (2–8) to that offender only.544. Re-run Lighthouse; confirm the metric moved and no other metric regressed.555. Repeat 2–4 until all budgets pass, then verify with real-user data after deploy.5657## Edge cases & failure modes58- **Lab passes, field fails** → trust field data; test on a low-end device profile and slow 4G; check geographic latency to origin (CDN).59- **LCP element is text** → the font is the bottleneck: preload it, subset it, check `font-display`.60- **Third-party script is required by the business** → load it after `load` event via a facade (static placeholder that loads the real widget on interaction); it cannot live in the critical path.61- **Framework hydration dominates JS cost** → move non-interactive parts to server components/static rendering; hydrate islands only.62- **No RUM available** → use CrUX (public, origin-level) as the field proxy; add `web-vitals` (npm) reporting when possible.6364## References65Copy-paste snippets and gotchas: see [references/patterns.md](references/patterns.md)66