Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsBlogPro
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges
  • Chrome Extension
  • Skill Manager

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Frontend Performance

ASecurity

Use when a ticket is about a slow or heavy frontend — page load, bundle size, Core Web Vitals (LCP, INP, CLS), a janky list, re-render storms, large images or fonts — and the fix must be measured in the browser before and after with the same tooling, not guessed. Invoke for "the page is slow", "reduce the bundle", "fix the layout shift", "the table lags when typing", or a failing performance budget.

2 stars
0 votes
0 copies
0 views
Added 9/28/2026
ai-agentsgoreactvueangularnodefrontendperformance

Works with

climcp

Security Analysis

A100/100

Scanned 9/29/2026

$npx -y skills add tmj-90/gaffer --skill frontend-performance --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Frontend Performance?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Frontend Performance
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tmj-90-frontend-performance/badge)](https://www.skillsdirectory.com/skills/tmj-90-frontend-performance)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
Files
SKILL.md
---
name: frontend-performance
description: Use when a ticket is about a slow or heavy frontend — page load, bundle size, Core Web Vitals (LCP, INP, CLS), a janky list, re-render storms, large images or fonts — and the fix must be measured in the browser before and after with the same tooling, not guessed. Invoke for "the page is slow", "reduce the bundle", "fix the layout shift", "the table lags when typing", or a failing performance budget.
stack: [react, web, next, vue, svelte, angular]
area: frontend
---

# Make the frontend fast, measurably

Performance is what the user's browser does: bytes shipped, main-thread work, layout
shifts. Measure the right metric, find the biggest cost, subtract it, and measure again
the same way. A change with no before/after number is not a performance fix.

## The targets (web.dev Core Web Vitals)

Assessed on **field data at the 75th percentile**, mobile and desktop separately:

| Metric | Good | Poor | What it measures |
|--------|------|------|------------------|
| LCP | ≤ 2.5 s | > 4 s | when the largest image/text block in the viewport renders |
| INP | ≤ 200 ms | > 500 ms | slowest-ish input → next paint across the visit (replaced FID in 2024) |
| CLS | ≤ 0.1 | > 0.25 | unexpected layout shift, largest session window |

Lab tools (Lighthouse) cannot measure INP; use **Total Blocking Time** as the lab proxy
and a scripted interaction trace for the specific slow input.

## Steps

1. **Pin the metric and the conditions.** Name one metric from the ticket (LCP, INP, CLS,
   route JS bytes gzipped, a component's commit time). Call `search_lore` for budgets and
   the measurement set-up. Record the baseline command and conditions, e.g.
   `npx --no -- lighthouse <url> --preset=perf --form-factor=mobile
   --throttling-method=simulate --chrome-flags="--headless=new" --output=json` run 5 times
   (report the median), or the repo's Lighthouse CI / bundle analyzer / `web-vitals`
   report. Use a production build, never the dev server. Use only tools already installed
   (installs are hook-blocked; headless, plain `npx` downloads a missing package, so write
   `npx --no -- <tool>`) — if none can measure the metric, say so in the evidence rather than
   guessing.
2. **Diagnose by sub-part, not by guess.**
   - **LCP** = TTFB + resource load delay + resource load duration + element render delay.
     Find which part dominates from the Lighthouse JSON (the LCP element and its phase
     breakdown) or a Playwright/Chrome trace — you have no interactive DevTools. Common causes: the LCP image is
     discovered late (CSS background, client-rendered, `loading="lazy"`), render-blocking
     CSS/fonts/JS, slow server response.
   - **INP** = input delay + processing duration + presentation delay. Script the slow
     interaction (Playwright plus a trace, or the `web-vitals` attribution build); look
     for long tasks (> 50 ms) before or inside
     the handler and for large re-renders or style/layout work after it. The `web-vitals`
     attribution build (`onINP(cb, { reportAllChanges: true })`) names the element and
     phase.
   - **CLS**: the Lighthouse layout-shift audit or the `web-vitals` attribution shows
     which node moved. Usual causes: images/iframes/
     ads without dimensions, late web fonts with different metrics, content injected above
     existing content, animations of layout properties.
   - **Bundle**: the analyzer (`vite-bundle-visualizer`, `@next/bundle-analyzer`,
     `source-map-explorer`) shows the top modules per route.
3. **Fix the dominant cost — subtract first.**
   - LCP: server-render or statically render the hero; make the LCP image discoverable in
     the HTML with `fetchpriority="high"` and never lazy; `preload` only it and the one
     critical font; inline critical CSS or cut render-blocking CSS; cache the HTML/CDN
     where the data allows (the `caching-strategy` skill).
   - INP: do less in the handler (update the visible state first, defer the rest); yield
     between chunks of work (`await scheduler.yield()` where supported, else
     `setTimeout(0)`); in React mark non-urgent updates with `startTransition` /
     `useDeferredValue`; virtualise long lists; avoid forced synchronous layout (reading
     `offsetHeight` after writing styles in a loop); move heavy pure work to a Web Worker.
   - CLS: `width`/`height` or `aspect-ratio` on all media and embeds; reserve space for
     late content (skeletons at the final size); fonts with `font-display: optional` or a
     metric-matched fallback (`size-adjust`, `ascent-override`); animate only `transform`
     and `opacity`.
   - Bytes: route- and component-level code splitting (`import()`); replace or deep-import
     heavy libraries; drop unneeded polyfills; defer third-party scripts; responsive images
     (`srcset`/`sizes`, AVIF/WebP) sized to their rendered box.
   - Also check back/forward cache eligibility (no `unload` handlers,
     no `Cache-Control: no-store` on HTML without reason) — bfcache makes back navigations
     instant.
4. **Re-render storms (React/Vue).** Count renders in a test (React `<Profiler>`
   `onRender`, or the framework's equivalent) rather than interactive devtools; fix the cause
   (state too high, unstable props, context carrying fast-changing values) before adding
   memoisation. If the React Compiler is enabled, do not hand-add `memo`/`useMemo`; if it
   is not, memoise only what the profiler shows is costly.
5. **Measure again** with the identical command and conditions, same number of runs;
   report median before/after and the spread. A change within run-to-run noise is not a
   win — say so.
6. **Guard it.** Add or tighten the budget the repo uses (Lighthouse CI assertion,
   `size-limit`, bundle-size check) for the metric you improved, so a regression fails CI.
7. **Evidence** via the `record-evidence` skill: the command, baseline and after medians,
   the dominant cost you removed, the bundle diff. Then stop.

## Done when

- The ticket's metric improved beyond noise under identical conditions, and meets the
  stated budget or the "good" threshold above if the ticket names none.
- No other Core Web Vital or route bundle regressed.
- Where the repo has budget tooling, a budget guards the improvement; otherwise the
  evidence names the missing guard (adding one is a `dependency-upgrade` decision).
  Functional tests still pass.

## Anti-patterns

- Measuring on the dev build, on a fast desktop only, or with one run.
- `loading="lazy"` or a fade-in animation on the LCP element; preloading many resources.
- Blanket `useMemo`/`React.memo` without a profile; debouncing a click instead of making
  the handler cheap.
- Skeletons whose size differs from the loaded content (they cause the shift they hide).
- Removing focus styles, labels or validation to improve a score.

## Capture lore

This skill is one of the places durable, reusable knowledge naturally surfaces:
**While measuring you learn the budgets, the heaviest dependencies and why they stay, and how the measurement is set up.** That kind of fact is *lore*. Capture it via the **lore-capture
protocol in your brief** (`CLAUDE.factory.md`, step 11 "Memory contribution"):
call the Memory MCP `suggest_lore` once at the close of your work — reusable
conventions, gotchas, decisions, and boundaries only, never per-ticket trivia.

Attribution

tmj-90tmj-90
View sourceSee grades on GitHubMore from tmj-90 →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Caveman

Terse caveman voice: answer first, fluff gone, every technical fact kept. Use for /caveman, "caveman mode", "talk like caveman", "be brief", "less tokens". Stays on until "stop caveman" or "normal mode".

1100021 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

698621 votes

Writing Skills

Create and manage Claude Code skills in HASH repository following Anthropic best practices. Use when creating new skills, modifying skill-rules.json, understanding trigger patterns, working with hooks, debugging skill activation, or implementing progressive disclosure. Covers skill structure, YAML frontmatter, trigger types (keywords, intent patterns), UserPromptSubmit hook, and the 500-line rule. Includes validation and debugging with SKILL_DEBUG. Examples include rust-error-stack, cargo-dep...

3931 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3421 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Amp, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Grok Build, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

741 votes
View all in ai-agents →