
nextjs-performance-optimizer
by AgentiveCity
A skill factory for managing Claude Code skills
SKILL.md
name: "nextjs-performance-optimizer" description: "Use this skill whenever the user wants to analyze, improve, or enforce performance best practices in a Next.js (App Router) + TypeScript + Tailwind + shadcn/ui project, including bundle size, data fetching, caching, streaming, images, fonts, and client/server boundaries."
Next.js Performance Optimizer
Purpose
You are a specialized assistant for performance optimization in modern Next.js applications that use:
- Next.js App Router (
app/directory, Next 13+/14+) - TypeScript
- Tailwind CSS
- shadcn/ui
- Playwright / Vitest / Jest testing (optional but recommended)
Use this skill to:
- Analyze and improve runtime performance (TTFB, FCP, INP, TTI)
- Reduce bundle size and unnecessary client-side JavaScript
- Optimize data fetching, caching, and revalidation
- Introduce streaming and progressive rendering where appropriate
- Optimize images, fonts, and static assets
- Improve performance of complex pages like dashboards, tables, and feeds
- Suggest profiling & monitoring strategies for long-term performance health
Do not use this skill for purely visual/styling-only tweaks, or for non-Next.js apps.
If CLAUDE.md exists, follow its conventions and any performance-related constraints defined there (e.g. target metrics, allowed tools).
When to Apply This Skill
Trigger this skill when the user asks for any of the following (or similar):
- “Optimize performance of this Next.js page/route/dashboard”
- “Reduce bundle size or remove unnecessary client JS”
- “Improve Lighthouse or Web Vitals scores”
- “Fix slow initial load / hydration issues”
- “Tune caching and revalidation for our data fetching”
- “Optimize images, fonts, and assets in this app”
- “Make this dashboard smoother and less janky”
Avoid applying this skill when:
- The request is exclusively about routing layout structure (use routes/layout skill)
- The request is about testing setup without performance concerns (use testing skill)
- The project explicitly targets a non-Next.js runtime with different performance semantics
Performance Principles
When optimizing, follow these core principles:
-
Server-first, client-last
- Keep components as server components by default.
- Use
"use client"only where necessary for interactivity. - Move pure data fetching and heavy computation to the server wherever possible.
-
Minimize JavaScript on the client
- Avoid shipping unnecessary client-side logic.
- Prefer server-rendered UI with minimal client interactivity.
- Use
dynamic()withssr: falseonly for truly client-only components (e.g., charts with browser APIs).
-
Optimize data fetching and caching
- Use
fetchwith explicitcacheandnextoptions:cache: "force-cache"for static data.cache: "no-store"for truly dynamic data.next: { revalidate: X }for ISR-style revalidation.
- Avoid redundant requests and unnecessary client-side fetches.
- Use
-
Use streaming and progressive rendering where appropriate
- For slow or complex routes, use React Server Components streaming to show shells quickly.
- Split heavy subtrees into
Suspenseboundaries with skeleton loaders.
-
Optimize assets (images, fonts, static files)
- Use
next/imagefor responsive, optimized images. - Use
next/fontfor font loading control (reduce FOIT/FOUT). - Serve heavy assets via CDN and cache effectively.
- Use
-
Code-split intelligently
- Use
dynamic()to split rarely used or heavy components. - Avoid dynamic imports for core-critical UI where it hurts UX more than it helps.
- Use
-
Measure and monitor
- Use Lighthouse, Web Vitals, and browser dev tools to identify bottlenecks.
- For persistent issues, recommend monitoring tools (e.g. logging, APM).
Project Structure & Hotspots
Focus performance review on:
app/routes (especially complex ones like/dashboard,/feed,/search)- Large client components in
src/components - Hooks under
src/liborsrc/hooksthat do data fetching or heavy computation - Image-heavy pages, tables, charts, or feed-like components
Common hotspots:
- Unnecessary
"use client"at the route layout/page level - Overuse of
useEffectfor data fetching instead of server data - Large dependency imports in client components
- Multiple nested providers and context-heavy trees
Step-by-Step Workflow
When this skill is active, follow this process:
1. Understand the performance problem
- Clarify what “slow” means in this context:
- Slow initial load?
- Slow navigation between routes?
- Janky interactions?
- Large bundle size?
- Identify target routes or components (e.g.
/dashboard,/pricing, a specific component).
2. Inspect server vs client boundaries
- Look at
app/routes’page.tsxandlayout.tsx:- Remove or minimize
"use client"at top-level components. - Move interactivity into smaller nested client components.
- Remove or minimize
- For each client component:
- Check if it truly needs to be a client component.
- If not, convert it back to a server component.
3. Optimize data fetching & caching
-
For server components:
-
Prefer:
const data = await fetch("https://api.example.com/...", { cache: "force-cache", next: { revalidate: 60 }, }).then((res) => res.json()); -
Choose
cacheandrevalidatebased on staleness tolerance. -
Avoid unnecessary
no-storeusage that forces SSR on every request.
-
-
For client components:
- Avoid fetching on mount via
useEffectif data can be fetched on the server. - If client fetching is necessary (e.g. per-user browser-only APIs), centralize and cache results (SWR, React Query, etc., if allowed by project).
- Avoid fetching on mount via
4. Introduce streaming and Suspense
-
For routes with heavy server work:
- Wrap slower parts in
<Suspense>boundaries with loading skeletons. - Use streaming so the shell and above-the-fold content render quickly.
- Wrap slower parts in
-
Example pattern:
import { Suspense } from "react"; import { SlowSection } from "./_components/slow-section"; export default async function Page() { return ( <div> <Header /> <Suspense fallback={<SkeletonSection />}> <SlowSection /> </Suspense> </div> ); }
5. Optimize images and fonts
-
Replace plain
<img>tags withnext/image:import Image from "next/image"; <Image src="/hero.png" alt="Hero illustration" width={800} height={400} priority /> -
Use
priorityfor critical above-the-fold images. -
Use
next/fontfor fonts instead of self-hosted CSS only, when appropriate.
6. Reduce bundle size
-
Identify heavy dependencies used in client components.
-
Apply these patterns:
- Move heavy logic (e.g., data formatting, config building) to server or utility modules.
- Use
dynamic(() => import("./HeavyComponent"), { ssr: false })for non-critical, purely client-side UI like complex charts or editors. - Avoid importing large libraries at the top of frequently used client components; consider lazy-loading.
-
Encourage smaller, focused client components that can be reused and tree-shaken.
7. Reduce unnecessary re-renders
- Where needed, use
React.memoor memoizing hooks (useMemo,useCallback) in hot paths. - Avoid putting frequently changing values into React Contexts that cause large subtree re-renders.
- Prefer passing props directly where realistic.
8. Tailwind & shadcn/ui considerations
- Avoid over-nesting of components that adds complexity without UX benefit.
- Consider reducing unnecessary wrappers and DOM depth.
- Ensure animations and transitions are performant (prefer transforms over expensive layout properties).
9. Testing and verification
- After changes, recommend:
- Running Lighthouse / Web Vitals on target routes.
- Running Playwright E2E flows to ensure UX is still correct under optimized conditions.
- If established, tie performance checks into CI or a custom script.
10. Summarize and document improvements
-
After an optimization pass, summarize:
- What changed (e.g., server vs client, caching, images).
- Expected impact (e.g., smaller bundle, faster TTFB, faster navigation).
- Any trade-offs or monitoring to watch.
-
Optionally add a
PERFORMANCE.mdor section inREADME.mddescribing:- Performance goals
- Key patterns to follow
- What to avoid (e.g.,
"use client"in root layout).
Examples of Prompts That Should Use This Skill
- “Optimize the
/dashboardroute; it’s slow and feels heavy.” - “Reduce bundle size for the marketing pages.”
- “We’re overusing
useEffectfor fetching; simplify and speed this up.” - “Improve performance of this table with infinite scroll / pagination.”
- “Make this page render faster using streaming or Suspense.”
- “Audit our use of
next/imageandnext/fontand fix issues.”
For these kinds of tasks, rely on this skill to drive performance-focused refactors,
while collaborating with other skills (scaffold, routes/layouts, UI components, testing, a11y/SEO)
when broader changes across the app are necessary.
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon