Claude Skills Guide

Claude Code Next.js Performance Optimization

Next.js performance optimization requires a systematic approach covering bundle analysis, runtime efficiency, and runtime performance. Claude Code combined with specialized skills can accelerate this process significantly.

Analyzing Bundle Size

Large JavaScript bundles directly impact initial load times and Time to Interactive (TTI). The first step is understanding what’s actually in your bundle.

Use the Bash tool to run bundle analysis:

npx next build && npx @next/bundle-analyzer

This generates a visual report showing which modules contribute most to bundle size. Claude Code can then help you interpret these results and identify optimization targets.

The frontend-design skill is particularly useful here—it understands component patterns and can suggest code splitting strategies specific to Next.js App Router. When you describe your page structure, it can recommend which components should use dynamic imports versus static imports.

Implementing Dynamic Imports

Code splitting at the component level reduces initial JavaScript payload. Next.js supports dynamic imports natively:

import dynamic from 'next/dynamic'

const HeavyChart = dynamic(
  () => import('../components/HeavyChart'),
  { 
    loading: () => <ChartSkeleton />,
    ssr: false
  }
)

The key decisions are ssr: false for client-only components and the loading fallback for perceived performance. Claude Code can audit your page components and suggest where dynamic imports would have the most impact.

Image Optimization Strategies

Images typically account for the largest portion of page weight. Next.js provides the next/image component, but proper configuration matters:

import Image from 'next/image'

export function HeroSection() {
  return (
    <Image
      src="/hero.png"
      alt="Product screenshot"
      width={1200}
      height={600}
      priority
      sizes="(max-width: 768px) 100vw, 50vw"
    />
  )
}

The priority prop preloads above-the-fold images, improving Largest Contentful Paint (LCP). The sizes attribute helps the browser select the appropriate image variant.

For more advanced image processing, the pdf skill can help if you’re generating reports with dynamic images—the skill understands how to optimize images within document generation contexts.

Route-Based Code Splitting

Next.js automatically splits code by route, but you can optimize further with Route Groups:

app/
├── (marketing)/
│   ├── page.tsx
│   └── layout.tsx
├── (app)/
│   ├── dashboard/
│   │   └── page.tsx
│   └── layout.tsx

Route Groups let you share layouts without bundling marketing code with dashboard code. This is especially valuable when the two sections have different dependency needs.

The tdd skill can help you write tests that verify route-based splitting works correctly—ensuring that code intended for one route doesn’t leak into another.

Reducing Client-Side JavaScript

Server Components in Next.js App Router reduce client-side JavaScript by default. The key is understanding which components truly need interactivity:

Audit your components with this pattern:

grep -r "'use client'" app/

Aim for Server Components as the default. Move interactivity to leaf components marked with 'use client'.

Runtime Performance

Bundle size affects load time, but runtime performance affects perceived responsiveness. Key areas include:

Memoization Strategy

React.memo, useMemo, and useCallback prevent unnecessary re-renders, but overusing them adds complexity without benefit:

'use client'

import { memo, useMemo } from 'react'

// Only memoize expensive computations
const ExpensiveList = memo(function ExpensiveList({ items }) {
  const sorted = useMemo(
    () => items.sort((a, b) => b.score - a.score),
    [items]
  )
  
  return (
    <ul>
      {sorted.map(item => (
        <ListItem key={item.id} item={item} />
      ))}
    </ul>
  )
})

Virtualization for Large Lists

Rendering thousands of items tanks performance. Use windowing libraries:

import { useVirtualizer } from '@tanstack/react-virtual'

function VirtualList({ items }) {
  const parentRef = useRef(null)
  
  const virtualizer = useVirtualizer({
    count: items.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 48,
  })
  
  return (
    <div ref={parentRef} style={{ height: '400px', overflow: 'auto' }}>
      <div style={{ height: virtualizer.getTotalSize() }}>
        {virtualizer.getVirtualItems().map(virtual => (
          <div
            key={virtual.key}
            style={{
              position: 'absolute',
              transform: `translateY(${virtual.start}px)`,
            }}
          >
            {items[virtual.index].name}
          </div>
        ))}
      </div>
    </div>
  )
}

Caching Strategies

Next.js provides multiple caching layers:

  1. Request Memoization: Automatic within React
  2. Data Cache: Persisted across builds
  3. Full Route Cache: Prerendered pages
  4. Router Cache: Client-side navigation

For dynamic data, use revalidate:

async function getData() {
  const res = await fetch('https://api.example.com/data', {
    next: { revalidate: 60 }
  })
  return res.json()
}

This caches the fetch result for 60 seconds, reducing database and API load.

Measuring Performance

Use the supermemory skill to track performance metrics over time. The skill can organize your benchmarks and help you correlate changes with performance improvements:

Run Lighthouse in CI to catch regressions:

npm install -D @lhci/cli

Configure .lighthouserc.js to establish performance budgets.

Automating Optimization Workflows

Combine Claude Code with your existing tooling. Create a skill that runs a performance audit:

# Performance audit script
npm run build
npx next build --analyze
lighthouse https://localhost:3000 --output json --output-path lighthouse-results.json

Claude Code can interpret these results and prioritize fixes based on impact.

Summary

Next.js performance optimization involves multiple layers: bundle size through code splitting, runtime performance through proper component architecture, and caching strategies for data fetching. Claude Code accelerates this process by analyzing your codebase, suggesting targeted optimizations, and helping you implement patterns like dynamic imports and virtualization.

The specialized skills like frontend-design, tdd, and supermemory each contribute to a comprehensive performance workflow—from design patterns that prevent performance issues, to tests that catch regressions, to memory systems that track improvements over time.

Start with bundle analysis, implement route-based and component-based code splitting, add image optimization, and layer on runtime optimizations as needed. Measure continuously to ensure your optimizations actually move the metrics that matter.

Built by theluckystrike — More at zovo.one