返回博客2026年4月1日2 分钟阅读

Vercel 部署 Next.js 项目的 10 个实用技巧

摘要

用 Vercel 部署 Next.js 不难,但要部署好有很多细节。这篇是我踩过的坑和总结的最佳实践,涵盖环境变量、ISR、Edge Functions、图片优化等。

Vercel + Next.js 是最顺手的部署组合,但 "能跑" 和 "跑得好" 之间差了很多细节。

我的博客和几个 SaaS 项目都部署在 Vercel 上。一年多下来,积累了不少经验和教训。这篇整理了 10 个最实用的技巧,帮你避开我踩过的坑。

一、环境变量的正确姿势

Vercel 的环境变量分三个作用域:Production、Preview、Development。很多人一股脑全选,结果 Preview 环境连了生产数据库。

最佳实践:

# Production 环境
DATABASE_URL=postgresql://prod-host/mydb
NEXT_PUBLIC_API_URL=https://api.example.com

# Preview 环境
DATABASE_URL=postgresql://staging-host/mydb
NEXT_PUBLIC_API_URL=https://staging-api.example.com

# Development 环境
DATABASE_URL=postgresql://localhost/mydb
NEXT_PUBLIC_API_URL=http://localhost:3001

注意 NEXT_PUBLIC_ 前缀的变量会被打包进客户端代码,所以绝对不要把密钥加这个前缀。

另一个常见坑:在 Vercel Dashboard 里改了环境变量后,需要重新部署才会生效。很多人改完等半天发现没效果,就是忘了这一步。

# 用 Vercel CLI 快速重新部署
vercel --prod

二、用 ISR 替代 SSR

如果你的页面数据不需要实时更新(比如博客文章、产品列表),用 ISR(Incremental Static Regeneration)比 SSR 好得多。

// app/blog/[slug]/page.tsx
export const revalidate = 3600; // 每小时重新生成

export default async function BlogPost({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug);
  return <Article post={post} />;
}

ISR 的好处:

  • 首次访问返回静态页面,速度极快
  • 后台定期重新生成,数据不会太旧
  • 不占用 Serverless Function 执行时间,省钱

实测一个博客页面,从 SSR 切到 ISR 后,TTFB 从 800ms 降到 50ms。

按需重新验证

不想等定时器?可以手动触发:

// app/api/revalidate/route.ts
import { revalidatePath } from "next/cache";
import { NextRequest } from "next/server";

export async function POST(request: NextRequest) {
  const { path, secret } = await request.json();

  if (secret !== process.env.REVALIDATION_SECRET) {
    return Response.json({ error: "Invalid secret" }, { status: 401 });
  }

  revalidatePath(path);
  return Response.json({ revalidated: true });
}

CMS 发布新文章时调一下这个接口,页面立刻更新。

三、Edge Functions 该用在哪

Vercel 的 Edge Functions 跑在边缘节点上,冷启动快、延迟低。但不是什么都适合放 Edge 上。

适合 Edge 的场景:

  • A/B 测试(根据 cookie 返回不同版本)
  • 地理位置相关的逻辑(根据用户所在国家显示不同内容)
  • 简单的 API 代理
  • 认证 / 重定向

不适合 Edge 的场景:

  • 需要连接数据库(Edge 环境的 TCP 支持有限)
  • 需要大量 Node.js API(Edge Runtime 是 V8 而非 Node.js)
  • CPU 密集型计算
// middleware.ts — 在 Edge 上运行
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function middleware(request: NextRequest) {
  const country = request.geo?.country || "US";

  // 中国用户重定向到 .cn 域名
  if (country === "CN" && !request.url.includes(".cn")) {
    return NextResponse.redirect("https://example.cn" + request.nextUrl.pathname);
  }

  return NextResponse.next();
}

export const config = {
  matcher: "/((?!api|_next|static).*)",
};

四、图片优化别偷懒

Next.js 的 <Image> 组件自带优化,但很多人没配好。

// next.config.js
module.exports = {
  images: {
    formats: ["image/avif", "image/webp"],
    remotePatterns: [
      {
        protocol: "https",
        hostname: "**.example.com",
      },
    ],
    // 自定义尺寸断点
    deviceSizes: [640, 750, 828, 1080, 1200],
    imageSizes: [16, 32, 48, 64, 96, 128, 256],
  },
};

几个关键点:

  1. 一定要设置 widthheight,否则布局偏移(CLS)分数会很差
  2. 首屏图片加 priority<Image priority src="..." />
  3. 非首屏图片用默认的 lazy loading,不需要额外设置
  4. fill 属性处理不知道尺寸的图片:
<div className="relative aspect-video">
  <Image src={cover} alt={title} fill className="object-cover" />
</div>

Vercel 的图片优化有免费额度(每月 5000 次图片转换),超了需要付费。如果图片量大,考虑用 Cloudflare Images 或者自己搭 imgproxy。

五、用 Vercel Analytics 而不是 Google Analytics

Vercel Analytics 有几个优势:

  • 不被 ad blocker 拦截——数据更准确
  • Web Vitals 实时监控——LCP、FID、CLS 一目了然
  • 零配置——装个包就行
npm install @vercel/analytics @vercel/speed-insights
// app/layout.tsx
import { Analytics } from "@vercel/analytics/react";
import { SpeedInsights } from "@vercel/speed-insights/next";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Analytics />
        <SpeedInsights />
      </body>
    </html>
  );
}

免费版每月 2500 次事件,个人项目够了。要更多数据就用 Pro 版。

六、Preview 部署是杀手级功能

每个 PR 自动生成一个 Preview URL,这是 Vercel 我最喜欢的功能。

用好它的关键:

  1. 给 Preview 配独立的环境变量——别连生产数据库
  2. 用 Preview 做 Code Review——Review PR 时直接点开看效果
  3. 自动化测试跑在 Preview 上——CI 里拿到 Preview URL,跑 E2E 测试
# GitHub Actions 示例
- name: Wait for Vercel Preview
  uses: patrickedqvist/wait-for-vercel-preview@v1.3.2
  with:
    token: ${{ secrets.GITHUB_TOKEN }}

- name: Run E2E Tests
  run: |
    PREVIEW_URL=${{ steps.wait.outputs.url }}
    npx playwright test --config=e2e.config.ts
  env:
    BASE_URL: ${{ steps.wait.outputs.url }}

七、构建缓存加速

Vercel 的构建缓存默认开启,但你可以进一步优化:

# 在 package.json 里指定缓存目录
{
  "scripts": {
    "build": "next build"
  },
  "vercel": {
    "buildCommand": "next build",
    "outputDirectory": ".next"
  }
}

加速技巧:

  • Turborepo:Monorepo 项目用 Turborepo,Vercel 原生支持远程缓存
  • 减少依赖npm ls --all | wc -l 看看你装了多少包,砍掉不需要的
  • standalone 输出:减少部署包体积
// next.config.js
module.exports = {
  output: "standalone",
};

八、自定义域名和 HTTPS

Vercel 配域名很简单,但有几个细节:

  1. 优先用 CNAME,而不是 A 记录——这样 Vercel 可以自动路由到最近的节点
  2. www 和裸域名——两个都配,然后设一个重定向到另一个
  3. SSL 证书自动续期——不需要手动管理,Vercel 用 Let's Encrypt 自动搞定
# DNS 配置
example.com    → A    76.76.21.21
www.example.com → CNAME cname.vercel-dns.com

九、Serverless Function 的超时陷阱

Hobby 版(免费)的 Serverless Function 超时是 60 秒,Pro 版可达 300 秒。听起来够用,但如果你的 API 需要做一些耗时操作(比如调用 AI API、批量处理),还是容易超时。

解决方案:

// 用 streaming response 避免超时
export async function GET(request: Request) {
  const encoder = new TextEncoder();
  const stream = new ReadableStream({
    async start(controller) {
      // 分步返回结果
      controller.enqueue(encoder.encode("处理中...\n"));

      const result = await longRunningTask();

      controller.enqueue(encoder.encode(JSON.stringify(result)));
      controller.close();
    },
  });

  return new Response(stream, {
    headers: { "Content-Type": "text/plain; charset=utf-8" },
  });
}

或者用 Vercel 的 maxDuration 配置(Pro 版):

export const maxDuration = 60; // 秒

十、监控和告警

项目上线后,监控比写代码更重要。

  1. Vercel Logs:实时查看 Function 日志,Debug 必备
  2. Integration with Sentry:错误追踪,一键安装
  3. Uptime Monitor:用 Better Uptime 或 Checkly 监控可用性
  4. Cost Alert:在 Vercel Dashboard 设置用量告警,防止账单爆炸
# Vercel CLI 查看实时日志
vercel logs --follow

总结

Vercel + Next.js 的开发体验确实很好,但生产级部署需要注意很多细节。回顾一下最重要的三点:

  1. 环境变量分环境管理——Preview 别连生产库
  2. 能用 ISR 就别用 SSR——性能差距巨大
  3. 图片优化和 Web Vitals 监控——用户体验的基本面

这些技巧不是一次性的——随着项目增长,每个点都值得定期 Review 和优化。

相关文章

2026年3月27日

用 Cloudflare Workers 部署 MCP 服务器

MCP 服务器不一定要跑在本地。这篇手把手教你用 Cloudflare Workers 部署一个远程 MCP 服务器,支持 SSE 传输,全球边缘节点加速。

MCPCloudflareWorkers

2026年2月17日

Next.js 正在为 AI Agent 重新设计自己

Next.js 团队发布了一篇博客,讲述他们如何从 Agent 的视角重新思考框架设计。从一个被放弃的浏览器内 Agent,到 MCP 集成,再到 agents.md - 这篇是我的阅读笔记。

Next.jsAI AgentMCP

合作伙伴

CompeteMap — 英国及爱尔兰学生竞赛一站式搜索

数学、编程、科学、写作等各类竞赛信息汇总,支持按年龄和科目筛选,再也不错过报名截止日。

准备开始了吗?

先简单说明目标,我会给出最合适的沟通方式。