nextjs-optimization
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNext.js 15 Optimization Skill
Next.js 15优化技巧
Objective
目标
Optimize Next.js applications to achieve:
- Perfect Core Web Vitals scores (LCP < 2.5s, FID < 100ms, CLS < 0.1)
- Fast page load times and optimal rendering strategies
- Efficient data fetching and caching
- Production-ready build configuration
- SEO and accessibility excellence
优化Next.js应用以实现:
- 完美的Core Web Vitals评分(LCP < 2.5秒,FID < 100毫秒,CLS < 0.1)
- 更快的页面加载速度与最优渲染策略
- 高效的数据获取与缓存机制
- 适用于生产环境的构建配置
- 卓越的SEO与可访问性
When to Use This Skill
何时使用该技巧
Auto-invoke when:
- Project uses Next.js (detected by in dependencies)
next - User mentions "optimize", "performance", "slow", or "Core Web Vitals"
- Before production deployment
- After adding new features or pages
- User requests Next.js-specific improvements
在以下场景自动调用:
- 项目使用Next.js(通过依赖中的检测)
next - 用户提及“优化”、“性能”、“缓慢”或“Core Web Vitals”
- 生产环境部署前
- 添加新功能或页面后
- 用户请求Next.js特定的改进方案
Prerequisites Check
前置条件检查
Tools: Read, Grep
-
Verify Next.js version:bash
# Read package.json # Check for "next": "^15.0.0" or higher -
Detect App Router (Next.js 13+):
- Check for directory
app/ - Check for ,
layout.tsxfilespage.tsx
- Check for
-
Detect Pages Router (Legacy):
- Check for directory
pages/ - Suggest migration to App Router
- Check for
工具:Read、Grep
-
验证Next.js版本:bash
# 读取package.json # 检查是否存在"next": "^15.0.0"或更高版本 -
检测App Router(Next.js 13+):
- 检查是否存在目录
app/ - 检查是否存在、
layout.tsx文件page.tsx
- 检查是否存在
-
检测Pages Router(旧版):
- 检查是否存在目录
pages/ - 建议迁移至App Router
- 检查是否存在
Optimization Categories
优化分类
1. Rendering Strategy Optimization
1. 渲染策略优化
Goal: Choose optimal rendering for each page/component
Tools: Read, Grep, Edit
目标:为每个页面/组件选择最优渲染方式
工具:Read、Grep、Edit
1.1 Server Components (Default in App Router)
1.1 Server Components(App Router默认)
When to use:
- Data fetching from APIs/databases
- Heavy computation
- Access to backend resources
Pattern:
typescript
// app/dashboard/page.tsx
export default async function DashboardPage() {
const data = await fetchData(); // Runs on server
return <Dashboard data={data} />;
}Check for violations:
bash
undefined适用场景:
- 从API/数据库获取数据
- 大量计算任务
- 访问后端资源
示例代码:
typescript
// app/dashboard/page.tsx
export default async function DashboardPage() {
const data = await fetchData(); // 在服务器端运行
return <Dashboard data={data} />;
}检查违规情况:
bash
undefinedSearch for "use client" in components that don't need it
搜索组件中不必要的"use client"声明
grep -r "use client" app/ | grep -v "onClick|useState|useEffect"
undefinedgrep -r "use client" app/ | grep -v "onClick|useState|useEffect"
undefined1.2 Client Components
1.2 Client Components
When to use:
- Interactive UI (onClick, forms)
- Browser APIs (window, localStorage)
- React hooks (useState, useEffect)
Pattern:
typescript
// app/components/Counter.tsx
'use client';
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}Optimization: Keep client components small and leaf nodes
适用场景:
- 交互式UI(onClick、表单)
- 浏览器API(window、localStorage)
- React钩子(useState、useEffect)
示例代码:
typescript
// app/components/Counter.tsx
'use client';
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}优化建议:保持Client Components为小型叶子节点组件
1.3 Static Generation (SSG)
1.3 静态生成(SSG)
When to use:
- Content that rarely changes
- Marketing pages, blogs, documentation
Pattern:
typescript
export const revalidate = 3600; // Revalidate every hour
export default async function BlogPost({ params }) {
const post = await getPost(params.slug);
return <Article post={post} />;
}适用场景:
- 内容极少变更
- 营销页面、博客、文档
示例代码:
typescript
export const revalidate = 3600; // 每小时重新验证一次
export default async function BlogPost({ params }) {
const post = await getPost(params.slug);
return <Article post={post} />;
}1.4 Dynamic Rendering with ISR
1.4 结合ISR的动态渲染
When to use:
- Content that changes periodically
- E-commerce products, user profiles
Pattern:
typescript
export const revalidate = 60; // Revalidate every minute
export async function generateStaticParams() {
const products = await getProducts();
return products.map((p) => ({ slug: p.slug }));
}适用场景:
- 内容定期变更
- 电商产品、用户资料
示例代码:
typescript
export const revalidate = 60; // 每分钟重新验证一次
export async function generateStaticParams() {
const products = await getProducts();
return products.map((p) => ({ slug: p.slug }));
}2. Image Optimization
2. 图片优化
Goal: Optimize images for performance and Core Web Vitals
Tools: Grep, Read, Edit
目标:优化图片以提升性能与Core Web Vitals指标
工具:Grep、Read、Edit
2.1 Use Next.js Image Component
2.1 使用Next.js Image组件
Find unoptimized images:
bash
grep -rn "<img " app/ src/Replace with:
typescript
import Image from 'next/image';
<Image
src="/hero.jpg"
alt="Hero image"
width={1200}
height={600}
priority // For above-the-fold images
placeholder="blur" // Optional blur-up effect
/>查找未优化的图片:
bash
grep -rn "<img " app/ src/替换为:
typescript
import Image from 'next/image';
<Image
src="/hero.jpg"
alt="首页英雄图"
width={1200}
height={600}
priority // 用于首屏可见图片
placeholder="blur" // 可选的模糊加载效果
/>2.2 Configure Image Domains
2.2 配置图片域名
Read next.config.js:
javascript
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
},
],
formats: ['image/avif', 'image/webp'], // Modern formats
},
};读取next.config.js:
javascript
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
},
],
formats: ['image/avif', 'image/webp'], // 现代图片格式
},
};2.3 Lazy Loading Strategy
2.3 懒加载策略
- priority: Above-the-fold images (LCP candidates)
- loading="lazy": Below-the-fold images (default)
- priority:首屏可见图片(LCP候选资源)
- loading="lazy":首屏以下图片(默认值)
3. Font Optimization
3. 字体优化
Goal: Eliminate FOUT/FOIT and improve font loading
Tools: Read, Edit
目标:消除FOUT/FOIT问题,优化字体加载
工具:Read、Edit
3.1 Use next/font
3.1 使用next/font
Pattern:
typescript
// app/layout.tsx
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap', // Prevent FOIT
variable: '--font-inter',
});
export default function RootLayout({ children }) {
return (
<html lang="en" className={inter.variable}>
<body>{children}</body>
</html>
);
}示例代码:
typescript
// app/layout.tsx
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap', // 避免FOIT
variable: '--font-inter',
});
export default function RootLayout({ children }) {
return (
<html lang="en" className={inter.variable}>
<body>{children}</body>
</html>
);
}3.2 Self-Hosted Fonts
3.2 自托管字体
typescript
import localFont from 'next/font/local';
const customFont = localFont({
src: './fonts/CustomFont.woff2',
display: 'swap',
variable: '--font-custom',
});typescript
import localFont from 'next/font/local';
const customFont = localFont({
src: './fonts/CustomFont.woff2',
display: 'swap',
variable: '--font-custom',
});4. Data Fetching Optimization
4. 数据获取优化
Goal: Minimize waterfalls and optimize cache
Tools: Read, Grep, Edit
目标:最小化请求瀑布流,优化缓存
工具:Read、Grep、Edit
4.1 Parallel Data Fetching
4.1 并行数据获取
Anti-pattern (Sequential):
typescript
const user = await getUser();
const posts = await getPosts(user.id); // Waits for userOptimized (Parallel):
typescript
const [user, posts] = await Promise.all([
getUser(),
getPosts(),
]);反模式(串行):
typescript
const user = await getUser();
const posts = await getPosts(user.id); // 等待用户数据返回优化后(并行):
typescript
const [user, posts] = await Promise.all([
getUser(),
getPosts(),
]);4.2 Streaming with Suspense
4.2 结合Suspense的流式渲染
Pattern:
typescript
import { Suspense } from 'react';
export default function Page() {
return (
<>
<Header />
<Suspense fallback={<Skeleton />}>
<SlowComponent />
</Suspense>
<Footer />
</>
);
}示例代码:
typescript
import { Suspense } from 'react';
export default function Page() {
return (
<>
<Header />
<Suspense fallback={<Skeleton />}>
<SlowComponent />
</Suspense>
<Footer />
</>
);
}4.3 Cache Configuration
4.3 缓存配置
typescript
// Aggressive caching
fetch('https://api.example.com/data', {
next: { revalidate: 3600 }, // Cache for 1 hour
});
// No caching
fetch('https://api.example.com/data', {
cache: 'no-store', // Always fresh
});
// Opt out of caching
export const dynamic = 'force-dynamic';typescript
// 激进缓存
fetch('https://api.example.com/data', {
next: { revalidate: 3600 }, // 缓存1小时
});
// 不缓存
fetch('https://api.example.com/data', {
cache: 'no-store', // 始终获取最新数据
});
// 禁用缓存
export const dynamic = 'force-dynamic';5. Bundle Optimization
5. 包体积优化
Goal: Reduce JavaScript bundle size
Tools: Bash, Read, Edit
目标:减小JavaScript包体积
工具:Bash、Read、Edit
5.1 Analyze Bundle
5.1 分析包体积
bash
undefinedbash
undefinedAdd to package.json scripts
添加到package.json的scripts中
npm run build
npx @next/bundle-analyzer
undefinednpm run build
npx @next/bundle-analyzer
undefined5.2 Dynamic Imports
5.2 动态导入
Find large components:
bash
find app -name "*.tsx" -exec wc -l {} \; | sort -rn | head -10Split with dynamic imports:
typescript
import dynamic from 'next/dynamic';
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
loading: () => <Skeleton />,
ssr: false, // Skip SSR if not needed
});查找大型组件:
bash
find app -name "*.tsx" -exec wc -l {} \; | sort -rn | head -10使用动态导入拆分:
typescript
import dynamic from 'next/dynamic';
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
loading: () => <Skeleton />,
ssr: false, // 不需要时跳过SSR
});5.3 Tree Shaking
5.3 摇树优化
Check for barrel exports:
bash
grep -rn "export \* from" app/Replace with specific imports:
typescript
// Anti-pattern
import { Button, Card, Modal } from '@/components';
// Optimized
import { Button } from '@/components/Button';检查桶导出:
bash
grep -rn "export \* from" app/替换为特定导入:
typescript
// 反模式
import { Button, Card, Modal } from '@/components';
// 优化后
import { Button } from '@/components/Button';6. Metadata & SEO
6. 元数据与SEO
Goal: Perfect SEO and social sharing
Tools: Read, Edit
目标:实现完美的SEO与社交分享效果
工具:Read、Edit
6.1 Static Metadata
6.1 静态元数据
typescript
// app/layout.tsx
export const metadata = {
title: {
default: 'My App',
template: '%s | My App',
},
description: 'Description for SEO',
openGraph: {
title: 'My App',
description: 'Description for social sharing',
images: ['/og-image.jpg'],
},
twitter: {
card: 'summary_large_image',
},
};typescript
// app/layout.tsx
export const metadata = {
title: {
default: '我的应用',
template: '%s | 我的应用',
},
description: 'SEO描述',
openGraph: {
title: '我的应用',
description: '社交分享描述',
images: ['/og-image.jpg'],
},
twitter: {
card: 'summary_large_image',
},
};6.2 Dynamic Metadata
6.2 动态元数据
typescript
export async function generateMetadata({ params }) {
const post = await getPost(params.slug);
return {
title: post.title,
description: post.excerpt,
openGraph: {
images: [post.ogImage],
},
};
}typescript
export async function generateMetadata({ params }) {
const post = await getPost(params.slug);
return {
title: post.title,
description: post.excerpt,
openGraph: {
images: [post.ogImage],
},
};
}7. Production Configuration
7. 生产环境配置
Goal: Optimize next.config.js for production
Tools: Read, Edit
目标:优化next.config.js以适配生产环境
工具:Read、Edit
7.1 Essential Config
7.1 核心配置
javascript
// next.config.js
module.exports = {
reactStrictMode: true,
poweredByHeader: false, // Security
compress: true, // Gzip compression
// Compiler optimizations
compiler: {
removeConsole: process.env.NODE_ENV === 'production',
},
// Image optimization
images: {
formats: ['image/avif', 'image/webp'],
deviceSizes: [640, 750, 828, 1080, 1200, 1920],
},
// React Compiler (Next.js 15)
experimental: {
reactCompiler: true,
},
};javascript
// next.config.js
module.exports = {
reactStrictMode: true,
poweredByHeader: false, // 安全优化
compress: true, // Gzip压缩
// 编译器优化
compiler: {
removeConsole: process.env.NODE_ENV === 'production',
},
// 图片优化
images: {
formats: ['image/avif', 'image/webp'],
deviceSizes: [640, 750, 828, 1080, 1200, 1920],
},
// React编译器(Next.js 15)
experimental: {
reactCompiler: true,
},
};7.2 Turbopack (Development)
7.2 Turbopack(开发环境)
json
// package.json
{
"scripts": {
"dev": "next dev --turbo"
}
}json
// package.json
{
"scripts": {
"dev": "next dev --turbo"
}
}8. Core Web Vitals Optimization
8. Core Web Vitals优化
Goal: Achieve perfect Lighthouse scores
Tools: Bash, Grep, Edit
目标:获得完美的Lighthouse评分
工具:Bash、Grep、Edit
8.1 LCP (Largest Contentful Paint) < 2.5s
8.1 LCP(最大内容绘制)< 2.5秒
Optimize:
- Use on hero images
priority - Preload critical resources
- Server-side render above-the-fold content
typescript
// Preload critical resources
<link rel="preload" href="/hero.jpg" as="image" />优化方案:
- 为英雄图添加属性
priority - 预加载关键资源
- 服务器端渲染首屏内容
typescript
// 预加载关键资源
<link rel="preload" href="/hero.jpg" as="image" />8.2 FID (First Input Delay) < 100ms
8.2 FID(首次输入延迟)< 100毫秒
Optimize:
- Minimize JavaScript execution
- Use dynamic imports for non-critical code
- Defer third-party scripts
typescript
import Script from 'next/script';
<Script
src="https://analytics.example.com"
strategy="lazyOnload" // Load after page interactive
/>优化方案:
- 最小化JavaScript执行时间
- 对非关键代码使用动态导入
- 延迟加载第三方脚本
typescript
import Script from 'next/script';
<Script
src="https://analytics.example.com"
strategy="lazyOnload" // 页面交互后加载
/>8.3 CLS (Cumulative Layout Shift) < 0.1
8.3 CLS(累积布局偏移)< 0.1
Optimize:
- Always specify image dimensions
- Reserve space for dynamic content
- Use
font-display: swap
css
/* Reserve space for ads/banners */
.ad-container {
min-height: 250px;
}优化方案:
- 始终指定图片尺寸
- 为动态内容预留空间
- 使用
font-display: swap
css
/* 为广告/横幅预留空间 */
.ad-container {
min-height: 250px;
}9. Caching Strategy
9. 缓存策略
Goal: Maximize cache hits and minimize server load
Tools: Read, Edit
目标:最大化缓存命中率,最小化服务器负载
工具:Read、Edit
9.1 Route Segment Config
9.1 路由段配置
typescript
// app/dashboard/page.tsx
export const revalidate = 3600; // ISR every hour
export const dynamic = 'auto'; // Automatic optimization
export const fetchCache = 'force-cache'; // Aggressive cachingtypescript
// app/dashboard/page.tsx
export const revalidate = 3600; // 每小时进行ISR
export const dynamic = 'auto'; // 自动优化
export const fetchCache = 'force-cache'; // 激进缓存9.2 Data Cache
9.2 数据缓存
typescript
// Deduplicated and cached automatically
const user = await fetch('https://api.example.com/user');
// Revalidate tag-based
export const revalidate = 60;
export const tags = ['user', 'profile'];typescript
// 自动去重并缓存
const user = await fetch('https://api.example.com/user');
// 基于标签的重新验证
export const revalidate = 60;
export const tags = ['user', 'profile'];10. Monitoring & Measurement
10. 监控与度量
Goal: Track performance over time
Tools: Bash, WebSearch
目标:持续跟踪性能变化
工具:Bash、WebSearch
10.1 Add Web Vitals Reporting
10.1 添加Web Vitals上报
typescript
// app/layout.tsx
import { SpeedInsights } from '@vercel/speed-insights/next';
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<SpeedInsights />
</body>
</html>
);
}typescript
// app/layout.tsx
import { SpeedInsights } from '@vercel/speed-insights/next';
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<SpeedInsights />
</body>
</html>
);
}10.2 Lighthouse CI
10.2 Lighthouse CI
bash
undefinedbash
undefinedRun Lighthouse
运行Lighthouse
npx lighthouse http://localhost:3000 --view
npx lighthouse http://localhost:3000 --view
Check Core Web Vitals
检查Core Web Vitals
npm run build
npm run start
npx lighthouse http://localhost:3000 --only-categories=performance
undefinednpm run build
npm run start
npx lighthouse http://localhost:3000 --only-categories=performance
undefinedOptimization Checklist
优化检查清单
Run through this checklist:
- All images use with proper dimensions
next/image - Fonts use with
next/fontdisplay: swap - Server Components used by default (no unnecessary 'use client')
- Client Components are leaf nodes and minimal
- Data fetching uses parallel requests where possible
- Slow components wrapped in
<Suspense> - Large components use dynamic imports
- Metadata configured for all pages
- has production optimizations
next.config.js - React Compiler enabled (Next.js 15)
- Bundle analyzed and optimized
- Core Web Vitals meet targets (test with Lighthouse)
逐一检查以下项:
- 所有图片均使用并指定正确尺寸
next/image - 字体使用并设置
next/fontdisplay: swap - 默认使用Server Components(无不必要的'use client')
- Client Components为叶子节点且体积最小
- 数据获取尽可能使用并行请求
- 缓慢组件包裹在中
<Suspense> - 大型组件使用动态导入
- 所有页面均配置元数据
- 包含生产环境优化配置
next.config.js - 启用React Compiler(Next.js 15)
- 分析并优化包体积
- Core Web Vitals达到目标值(使用Lighthouse测试)
Output Format
输出格式
markdown
undefinedmarkdown
undefinedNext.js Optimization Report
Next.js优化报告
Current Status
当前状态
- Next.js Version: 15.0.3
- Rendering: App Router
- React Version: 19.0.0
- Next.js版本: 15.0.3
- 渲染模式: App Router
- React版本: 19.0.0
Issues Found
发现的问题
🔴 Critical (3)
🔴 严重问题(3项)
-
Unoptimized Images: 12tags found
<img>- Files: ,
app/page.tsxapp/about/page.tsx - Fix: Replace with
next/image
- Files:
-
Large Client Bundle: 342 KB (target: < 200 KB)
- Cause: Heavy chart library loaded synchronously
- Fix: Use dynamic import for component
Chart
-
Missing Font Optimization: Using Google Fonts via <link>
- Fix: Migrate to
next/font/google
- Fix: Migrate to
-
未优化图片: 发现12个标签
<img>- 文件: ,
app/page.tsxapp/about/page.tsx - 修复方案: 替换为
next/image
- 文件:
-
客户端包体积过大: 342 KB(目标: < 200 KB)
- 原因: 同步加载大型图表库
- 修复方案: 对组件使用动态导入
Chart
-
字体未优化: 通过<link>标签加载Google Fonts
- 修复方案: 迁移至
next/font/google
- 修复方案: 迁移至
🟡 Warnings (2)
🟡 警告(2项)
- Sequential Data Fetching: Waterfall detected in
app/dashboard/page.tsx - No Metadata: Missing OpenGraph tags on 5 pages
- 串行数据获取: 中存在请求瀑布流
app/dashboard/page.tsx - 缺失元数据: 5个页面缺少OpenGraph标签
Optimizations Applied
已应用的优化
✅ Enabled React Compiler in next.config.js
✅ Added image optimization config
✅ Configured proper cache headers
✅ Added Suspense boundaries to slow routes
✅ 在next.config.js中启用React Compiler
✅ 添加图片优化配置
✅ 配置正确的缓存头
✅ 为缓慢路由添加Suspense边界
Performance Impact (Estimated)
性能影响(预估)
- Load Time: 3.2s → 1.8s (-44%)
- Bundle Size: 342 KB → 198 KB (-42%)
- LCP: 3.1s → 2.3s (✅ Good)
- FID: 85ms → 45ms (✅ Good)
- CLS: 0.15 → 0.05 (✅ Good)
- 加载时间: 3.2秒 → 1.8秒(-44%)
- 包体积: 342 KB → 198 KB(-42%)
- LCP: 3.1秒 → 2.3秒(✅ 达标)
- FID: 85毫秒 → 45毫秒(✅ 达标)
- CLS: 0.15 → 0.05(✅ 达标)
Next Steps
后续步骤
- Replace 12 tags with
<img>next/image - Split Chart component with dynamic import
- Add metadata to 5 pages
- Run Lighthouse to verify improvements
undefined- 将12个标签替换为
<img>next/image - 使用动态导入拆分Chart组件
- 为5个页面添加元数据
- 运行Lighthouse验证改进效果
undefinedBest Practices
最佳实践
- Server-First Mindset: Default to Server Components
- Progressive Enhancement: Build for slow networks first
- Measure, Don't Guess: Use Lighthouse and Web Vitals
- Cache Aggressively: But revalidate appropriately
- Optimize Incrementally: Fix critical issues first
- 服务器优先思维: 默认使用Server Components
- 渐进式增强: 优先为低速网络环境构建
- 度量而非猜测: 使用Lighthouse和Web Vitals工具
- 激进缓存: 但需合理配置重新验证策略
- 增量优化: 优先修复严重问题
Integration with Other Skills
与其他技巧的集成
- - Detect Next.js project and version
codebase-analysis - - Run build and verify no regressions
quality-gates - - Ensure React 19 best practices
react-patterns - - Add performance tests
testing-strategy
- - 检测Next.js项目及版本
codebase-analysis - - 运行构建并验证无回归
quality-gates - - 确保遵循React 19最佳实践
react-patterns - - 添加性能测试
testing-strategy
Common Anti-Patterns to Avoid
需避免的常见反模式
❌ Using 'use client' at the top level
❌ Not specifying image dimensions
❌ Synchronous data fetching
❌ Loading entire component libraries
❌ No Suspense boundaries
❌ Ignoring Core Web Vitals
❌ 在顶层使用'use client'
❌ 未指定图片尺寸
❌ 串行数据获取
❌ 加载完整的组件库
❌ 未添加Suspense边界
❌ 忽略Core Web Vitals指标
Version History
版本历史
- 1.0.0 (2025-01-03): Initial skill for Next.js 15 with App Router focus
- 1.0.0(2025-01-03):针对Next.js 15的初始版本,重点关注App Router