Skip to content
Back to skills

Optimize Performance

ASecurity

Use when tuning frontend performance — enables the React Compiler, splits code by route and lazy-loads heavy chunks, adds bundle analysis with a size budget, measures Core Web Vitals (LCP/INP/CLS) with web-vitals, and applies image/CLS best practices. Measure first, then optimize.

  • 5 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 9, 2026
developmentgobashreactvuefrontendperformance

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 2 files and shows the line behind each finding

Scanned October 9, 2026

npx -y skills add VelimirMueller/vlm-code-context-mcp --skill optimize-performance --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Optimize Performance?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Optimize Performance
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/velimirmueller-optimize-performance/badge)](https://www.skillsdirectory.com/skills/velimirmueller-optimize-performance)

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

Download with Pro
SKILL.md
---
name: optimize-performance
description: Use when tuning frontend performance — enables the React Compiler, splits code by route and lazy-loads heavy chunks, adds bundle analysis with a size budget, measures Core Web Vitals (LCP/INP/CLS) with web-vitals, and applies image/CLS best practices. Measure first, then optimize.
---

# Optimize Performance

## 1. Audit current state

```bash
grep -E '"(babel-plugin-react-compiler|rollup-plugin-visualizer|web-vitals)"' package.json 2>/dev/null
grep -rn "React.lazy\|defineAsyncComponent\|loading=\"lazy\"" src/ 2>/dev/null | head
```

**Prerequisites:** `scaffold-frontend-project` (Vite) and ideally `set-up-routing` (route-level splitting). **Rule zero: measure before optimizing** — wire the analyzer + vitals (steps 6–7) before hand-tuning anything.

## 2. Decide what to do
- Greenfield → enable Compiler + splitting + measurement (steps 4–8).
- Slow app → measure first (6–7), then attack the biggest chunk / worst vital.

## 3. Detect framework
React → React Compiler + `React.lazy`. Vue → the SFC compiler is already optimal; lazy via `defineAsyncComponent`, and `v-memo`/`v-once` for proven hotspots only.

## 4. Enable the React Compiler (React)

The compiler auto-memoizes — it removes the need for most `useMemo`/`useCallback`/`memo`. It's GA in React 19.

```bash
pnpm add -D babel-plugin-react-compiler
```
```ts
// vite.config.ts
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [
    // if set-up-routing ran, tanstackRouter() goes FIRST (before react)
    react({ babel: { plugins: [['babel-plugin-react-compiler', {}]] } }), // compiler = build-time transform
    // then tailwindcss()
  ],
});
```

The compiler relies on the Rules of React; add `eslint-plugin-react-hooks` (v5+, which ships the compiler rules) alongside Biome **for React rule-checking only** if you want lint-time guarantees — Biome doesn't cover those yet. After enabling, delete redundant `useMemo`/`useCallback` (keep Zustand selectors — different axis; see `set-up-state-management`).

## 5. Split code by route, lazy-load the heavy stuff

- **Routes:** already split if `set-up-routing` ran (TanStack `autoCodeSplitting` / Vue dynamic `import()`).
- **Heavy non-route components** (charts, editors, modals below the fold):
```tsx
const Chart = lazy(() => import('@/components/organisms/Chart')); // React
// Vue: const Chart = defineAsyncComponent(() => import('@/components/organisms/Chart.vue'))
```
Wrap in `<Suspense>`. Let Vite handle vendor splitting; only add `build.rollupOptions.output.manualChunks` for a *measured* win.

## 6. Bundle analysis + a budget

```bash
pnpm add -D rollup-plugin-visualizer
```
```ts
// vite.config.ts (dev-only-ish; gate behind an env flag)
import { visualizer } from 'rollup-plugin-visualizer';
// plugins: [..., visualizer({ filename: 'dist/stats.html', gzipSize: true })]
```
`pnpm build` then open `dist/stats.html`. Set a budget (e.g. initial JS < 200 KB gzipped) and enforce it with **`size-limit`** (`pnpm add -D size-limit @size-limit/preset-app`, add a `size-limit` array to `package.json`, run `pnpm size-limit` in CI) so regressions fail the build, not just the eyeball.

## 7. Measure Core Web Vitals

```bash
pnpm add web-vitals
```
```ts
// src/libs/reportWebVitals.ts
import { onCLS, onINP, onLCP } from 'web-vitals';

export function reportWebVitals(report: (m: { name: string; value: number }) => void) {
  onCLS(report);
  onINP(report); // INP replaced FID in 2024
  onLCP(report);
}
```
Call it once from the app entry; send to analytics (or the `captureError`-style seam) in prod, `console.log` in dev.

## 8. Images & layout stability
- Always set `width`/`height` (or `aspect-ratio`) so images don't shift layout (**CLS**).
- `loading="lazy"` + `decoding="async"` for below-the-fold images.
- Serve AVIF/WebP; `vite-imagetools` generates responsive `srcset` at build time.
- Preload the LCP image/font; `font-display: swap`.

## 9. Verify
```bash
pnpm build          # inspect dist/stats.html against the budget
pnpm preview        # run Lighthouse / read web-vitals in console
```
Targets: **LCP ≤ 2.5 s, INP ≤ 200 ms, CLS ≤ 0.1** (mobile, mid-tier device).

## References
- ./performance-rules.md — measure-first, the Compiler's effect, splitting strategy, CWV targets, image/CLS rules, when manual memo still matters.
- ../_shared/conventions.md — `@/` alias, `libs/` seam.
- ../_shared/stack-versions.md — tooling versions.
- ../../landing/build-landing-page/SKILL.md — the hero LCP/CLS budget on public pages, where CWV are ranking + revenue (the priority inversion: `../../landing/_shared/page-types.md`).

Files in this skill

  • SKILL.md4.6 KB
  • performance-rules.md2.9 KB

Attribution

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

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.