切换语言
切换主题

Next.js 15实战:我是如何用一个周末搭建出生产级博客系统的

引言

我还记得两个月前的某个周五晚上,公司项目刚上线,我打开电脑想学点新东西放松一下。Next.js 15刚发布不久,官方文档看了好几遍,各种教程视频也刷了不少,但总感觉停留在纸上谈兵的阶段——什么Server Actions、App Router,概念都懂,就是不知道实际项目里怎么用。
你肯定也有这种感觉吧?看完教程热血沸腾,关掉浏览器立马懵了,这东西到底能拿来干啥?
所以那个周末,我决定不再看教程了,直接撸起袖子做个真实的项目——一个全栈博客系统。说实话,一开始我也没信心能做出来,毕竟涉及前端、后端、数据库、部署,听起来挺吓人的。但两天后,当我看到自己搭建的博客成功部署到Vercel,Lighthouse性能评分达到96分的时候,那种成就感真的无法形容。
这篇文章我会把整个过程分享给你,不是那种复制粘贴代码就完事的教程,而是真正带你理解为什么要这么做,以及我踩过哪些坑。技术栈是Next.js 15 + Server Actions + Prisma + PostgreSQL,都是生产级的代码,不是玩具项目。
如果你也想在一个周末掌握Next.js全栈开发,那就跟着我的节奏来吧。

为什么选择Next.js 15?

选技术栈这事儿,我纠结了好久。
Next.js 15刚出的时候,我在社区看到有人吐槽”又TM更新了,学不动了”。老实讲,我当时也有点抵触,毕竟14还没完全搞明白呢。但仔细研究了一下新特性后,我发现这次升级是真的香。

Server Actions:告别API Routes的繁琐

以前做全栈开发,最烦的就是写API Routes。创建一个api/posts/route.ts,定义POST方法,处理请求体,返回响应…每次都是这套流程,写到吐。
Server Actions彻底改变了这个玩法。你只需要在函数前加个'use server',然后直接在组件里调用就行了。我第一次看到这个特性时,心里想的是”这不就是把后端代码写前端了吗?“但试了一次后——真香!
举个例子,以前创建博客文章要这么写:

// 老方法:需要创建API Route
// app/api/posts/route.ts
export async function POST(request: Request) {
  const body = await request.json()
  // 一堆处理逻辑...
}
// 前端还要fetch调用
const response = await fetch('/api/posts', {
  method: 'POST',
  body: JSON.stringify(data)
})

现在直接这样:

// app/actions/post-actions.ts
'use server'
export async function createPost(formData: FormData) {
  const title = formData.get('title')
  const content = formData.get('content')
  // 直接操作数据库,是不是很爽?
  return await prisma.post.create({
    data: { title, content }
  })
}

在组件里调用就跟调本地函数一样简单。用个生活化的比喻:以前是你要自己去餐厅取外卖(API Routes),现在是外卖直送到家(Server Actions)。

Turbopack让开发快了一倍不止

Next.js 15把Turbopack从实验性变成了稳定版。官方说本地服务器启动快76.7%,代码更新快96.3%,我一开始以为是营销数字,实际用了后发现——没吹牛。

76.7%
服务器启动速度提升
官方测试数据
96.3%
代码更新速度提升
热更新几乎瞬间完成
2秒
项目启动时间
30多个组件从7-8秒压缩到2秒以内

我的项目大概有30多个组件,用Webpack的话启动要7-8秒,Turbopack直接压缩到2秒以内。改个代码,热更新几乎是瞬间完成。这对开发体验的提升,不是一点半点。

为什么这个技术栈适合博客?

选Next.js做博客,主要看中三点:
SSR/SSG天然优势——博客最重要的是SEO,Next.js的服务端渲染和静态生成天生就是为这个场景设计的。Google爬虫直接拿到完整的HTML,比纯客户端渲染的React强太多了。
Prisma的类型安全——我以前用过Mongoose写MongoDB,类型定义全靠手动维护,一不小心就出bug。Prisma直接从schema生成TypeScript类型,写代码的时候有完整的智能提示,基本不会出错。
Server Actions简化开发——不用写API Routes了,代码量至少减少30%。我这个博客系统,如果用传统方式写,估计要多写好几个route.ts文件。

技术栈选型与架构设计

搞清楚为什么后,接下来就是具体怎么做了。

我的完整技术栈

  • 前端: Next.js 15 + TypeScript + Tailwind CSS
  • 后端: Next.js Server Actions + NextAuth.js
  • 数据库: PostgreSQL + Prisma ORM
  • 部署: Vercel
    你可能会想,为什么不用MongoDB?其实我一开始也这么想,MongoDB确实更灵活。但后来发现Prisma对PostgreSQL的支持更好,而且关系型数据库在处理博客文章、用户、评论这种关系明确的数据时,反而更合适。

目录结构长这样

my-blog/
├── app/
│   ├── (auth)/          # 认证相关页面
│   ├── blog/            # 博客相关页面
│   │   └── [slug]/      # 动态路由
│   ├── dashboard/       # 用户控制面板
│   ├── actions/         # Server Actions都放这里
│   └── api/auth/        # NextAuth配置
├── components/          # 可复用组件
├── lib/
│   ├── prisma.ts        # Prisma单例(这个很重要!)
│   └── utils.ts         # 工具函数
├── prisma/
│   └── schema.prisma    # 数据库Schema
└── public/              # 静态资源

这个结构我改了好几版才定下来。一开始我把Server Actions散落在各个页面文件里,后来发现维护起来太乱,专门建了个actions目录统一管理,清爽多了。

数据库Schema设计

数据库设计这块,我踩了个大坑。第一版我设计得过于复杂,什么标签、分类、阅读统计全加上了,结果写到一半发现根本用不上这么多表,又花了半天时间简化。
最后定下来的核心Schema是这样的:

// prisma/schema.prisma
generator client {
  provider = "prisma-client-js"
}
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}
model User {
  id        String   @id @default(cuid())
  email     String   @unique
  name      String?
  image     String?
  posts     Post[]
  createdAt DateTime @default(now())
}
model Post {
  id          String   @id @default(cuid())
  title       String
  slug        String   @unique
  content     String   @db.Text
  published   Boolean  @default(false)
  authorId    String
  author      User     @relation(fields: [authorId], references: [id])
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
  @@index([slug])
  @@index([authorId])
}

注意看那两个@@index,这是性能优化的关键。博客列表页经常要按slug查询,用户主页要按authorId筛选,加上索引后查询速度能提升好几倍。

核心功能实现详解

好了,架构规划完,接下来是最刺激的部分——写代码!

3.1 环境搭建与初始化

创建Next.js 15项目超级简单:

npx create-next-app@latest my-blog
cd my-blog
npm install prisma @prisma/client zod next-auth

安装完Prisma后,初始化:

npx prisma init

这会生成prisma/schema.prisma.env文件。在.env里配置PostgreSQL连接:

DATABASE_URL="postgresql://username:password@localhost:5432/myblog?schema=public"

本地开发我用的是Docker跑PostgreSQL,一行命令搞定:

docker run --name blog-postgres -e POSTGRES_PASSWORD=mypassword -p 5432:5432 -d postgres

3.2 Prisma数据库集成

配置好Schema后,运行migration:

npx prisma migrate dev --name init

这里要特别注意一个坑——Prisma Client的单例模式。我第一次部署到Vercel的时候,完全忘了配置这个,结果网站跑了半天就报”Too many connections”错误,吓得我以为被DDoS攻击了。
原来是Next.js开发环境会热重载,每次重载都创建新的Prisma Client实例,连接池很快就爆了。正确的做法是这样:

// lib/prisma.ts
import { PrismaClient } from '@prisma/client'
const globalForPrisma = globalThis as unknown as {
  prisma: PrismaClient | undefined
}
export const prisma = globalForPrisma.prisma ?? new PrismaClient()
if (process.env.NODE_ENV !== 'production') {
  globalForPrisma.prisma = prisma
}

这段代码看起来有点绕,但它保证了开发环境下只有一个Prisma实例,生产环境不受影响。记住了,这是Prisma官方推荐的最佳实践!

3.3 Server Actions实战应用

创建博客文章是核心功能,来看看Server Actions怎么写:

// app/actions/post-actions.ts
'use server'
import { prisma } from '@/lib/prisma'
import { revalidatePath } from 'next/cache'
import { z } from 'zod'
// 用Zod做数据验证,类型安全拉满
const PostSchema = z.object({
  title: z.string().min(1, '标题不能为空').max(100),
  content: z.string().min(10, '内容至少10个字'),
  slug: z.string().regex(/^[a-z0-9-]+$/, 'slug只能包含小写字母、数字和横杠')
})
export async function createPost(formData: FormData) {
  // 验证数据
  const validatedFields = PostSchema.safeParse({
    title: formData.get('title'),
    content: formData.get('content'),
    slug: formData.get('slug')
  })
  if (!validatedFields.success) {
    return { error: '数据验证失败' }
  }
  try {
    const post = await prisma.post.create({
      data: {
        ...validatedFields.data,
        authorId: 'user-id-here' // 实际项目从session获取
      }
    })
    // 重新验证缓存,这样新文章立即显示
    revalidatePath('/blog')
    return { success: true, post }
  } catch (error) {
    return { error: '创建文章失败' }
  }
}

在组件里直接用:

// app/dashboard/new-post/page.tsx
import { createPost } from '@/app/actions/post-actions'
export default function NewPost() {
  return (
    <form action={createPost}>
      <input name="title" placeholder="标题" />
      <textarea name="content" placeholder="内容" />
      <input name="slug" placeholder="URL slug" />
      <button type="submit">发布</button>
    </form>
  )
}

看到没?不需要useState,不需要fetch,甚至不需要onSubmit事件处理。表单直接调用Server Action,Next.js自动处理序列化、网络请求、错误处理这些脏活累活。
一开始我也搞不清楚Server Actions和API Routes的区别,后来才明白:Server Actions就像”点外卖直送”,API Routes是”自己去餐厅取”。前者方便,后者灵活。大部分场景下,Server Actions够用了。

3.4 用户认证系统

认证这块我用的是NextAuth.js,配置起来挺简单:

// app/api/auth/[...nextauth]/route.ts
import NextAuth from 'next-auth'
import GitHubProvider from 'next-auth/providers/github'
import { PrismaAdapter } from '@auth/prisma-adapter'
import { prisma } from '@/lib/prisma'
export const authOptions = {
  adapter: PrismaAdapter(prisma),
  providers: [
    GitHubProvider({
      clientId: process.env.GITHUB_ID!,
      clientSecret: process.env.GITHUB_SECRET!
    })
  ]
}
const handler = NextAuth(authOptions)
export { handler as GET, handler as POST }

配置GitHub OAuth需要在GitHub Developer Settings创建一个应用,拿到Client ID和Secret填到.env里就行。整个过程10分钟搞定,比自己写JWT认证省事太多了。

3.5 SSR/SSG优化策略

这部分是性能优化的关键。说实话,一开始我全用SSR(服务端渲染),结果发现每次打开博客列表都要查数据库,完全没必要。后来改成混合策略:
博客列表页——SSG + ISR:

// app/blog/page.tsx
import { prisma } from '@/lib/prisma'
// 每小时重新生成一次
export const revalidate = 3600
export default async function BlogList() {
  const posts = await prisma.post.findMany({
    where: { published: true },
    orderBy: { createdAt: 'desc' }
  })
  return (
    <div>
      {posts.map(post => (
        <article key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.content.slice(0, 150)}...</p>
        </article>
      ))}
    </div>
  )
}

这个页面在构建时就生成了静态HTML,之后每小时自动重新生成。用户访问时直接拿静态文件,速度飞快。
博客详情页——动态SSR:

// app/blog/[slug]/page.tsx
export default async function Post({ params }: { params: { slug: string } }) {
  const post = await prisma.post.findUnique({
    where: { slug: params.slug }
  })
  if (!post) notFound()
  return (
    <article>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.content }} />
    </article>
  )
}

这个每次访问都会查数据库拿最新内容,适合经常更新的文章。
性能对比数据:

~200ms
SSG页面加载时间
静态生成,速度最快
~800ms
SSR页面加载时间
服务端渲染,适合动态内容
~1500ms
纯CSR加载时间
客户端渲染,SEO较差

差距一目了然吧?这就是为什么Next.js适合做博客——SEO好,性能还强。

部署上线与优化

代码写完了,最激动人心的时刻到了——部署!

Vercel部署流程

我把代码推到GitHub后,直接在Vercel导入仓库。Vercel检测到是Next.js项目,自动配置好了一切。唯一要手动配置的是环境变量:

DATABASE_URL="你的生产数据库连接"
GITHUB_ID="OAuth Client ID"
GITHUB_SECRET="OAuth Secret"
NEXTAUTH_URL="https://your-domain.vercel.app"
NEXTAUTH_SECRET="随机字符串"

生产数据库我用的是Supabase的免费PostgreSQL,每月有500MB额度,个人博客完全够用。
点击Deploy后,大概2分钟网站就上线了。第一次看到自己的域名能访问时,我盯着屏幕看了好几秒,然后忍不住截图发朋友圈。

生产环境优化

部署成功不代表结束,还有几个优化要做:
Prisma连接池配置:

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
  // Vercel Serverless环境必须设置
  directUrl = env("DIRECT_URL")
}

Serverless环境下,每个函数调用都可能创建新连接,设置directUrl可以复用连接池。
图片优化:

import Image from 'next/image'
<Image
  src="/avatar.jpg"
  alt="用户头像"
  width={100}
  height={100}
  // Next.js自动压缩优化
/>

Next.js的Image组件会自动转换成WebP格式,按需加载,性能提升明显。
最终性能评分:

96分
Lighthouse桌面端性能分

我用Lighthouse跑了一下,桌面端性能96分,移动端92分,SEO 100分。看到这个结果时,真的很有成就感——两天时间,从零到上线,还是生产级的性能。

扩展方向与学习资源

这个博客系统目前是MVP版本,还有很多可以加的功能:

  • Markdown编辑器: 可以集成react-md-editor
  • 评论系统: 考虑接入Giscus(基于GitHub Discussions)
  • 搜索功能: Algolia或者自己用Prisma全文搜索
  • 深色模式: 用next-themes很容易实现
    我接下来打算先加个Markdown编辑器,写文章会方便很多。
    推荐学习资源:
  • Next.js官方文档 - 永远是最权威的
  • Prisma文档 - 把Getting Started看一遍就够了
  • 这个项目的完整代码 - 可以直接clone下来跑
    相信我,动手做一遍比看十遍文档有用。你学会了理论,但只有实战才能真正掌握。

总结

回顾一下,这个周末项目我学到了:

  1. Server Actions的强大: 真的可以替代大部分API Routes,开发效率提升不是一点半点
  2. Prisma的类型安全: 有了完整的TypeScript支持,写代码特别有安全感
  3. SSG/SSR的灵活性: 根据场景选择渲染策略,性能和SEO都能兼顾
  4. Vercel部署的简单: 从代码到上线,不到5分钟
    老实讲,做完这个项目最大的收获不是技术本身,而是信心——原来全栈开发也没那么难,关键是要动手。
    如果你也想搭建一个自己的博客系统,别犹豫,现在就开始吧!遇到问题很正常,我当时也是边查文档边写代码,踩了无数坑才跑通。但当你看到自己的作品上线的那一刻,所有的努力都值得。
    希望这篇文章能帮你少走些弯路。有问题欢迎在评论区讨论,我会尽量回复。
    期待看到你的作品!

用Next.js 15搭建生产级博客系统完整流程

从环境搭建到部署上线的完整步骤,包含Server Actions、Prisma、SSG/SSR优化等核心功能实现

⏱️ 预计耗时: 16 小时

  1. 1

    步骤1: 环境搭建与项目初始化

    创建Next.js 15项目:
    • 运行:npx create-next-app@latest my-blog
    • cd my-blog进入项目目录

    安装依赖:
    • npm install prisma @prisma/client zod next-auth

    初始化Prisma:
    • 运行:npx prisma init
    • 生成prisma/schema.prisma和.env文件

    配置数据库连接:
    • 在.env里配置:
    DATABASE_URL="postgresql://username:password@localhost:5432/myblog?schema=public"

    本地开发使用Docker运行PostgreSQL:
    • docker run --name blog-postgres -e POSTGRES_PASSWORD=mypassword -p 5432:5432 -d postgres
  2. 2

    步骤2: 配置Prisma数据库Schema

    设计核心Schema:

    User模型:
    • id、email、name、image
    • posts关系、createdAt字段

    Post模型:
    • id、title、slug、content、published
    • authorId、author关系
    • createdAt、updatedAt字段

    关键优化:
    • 在Post模型上添加@@index([slug])和@@index([authorId])索引
    • 博客列表页经常要按slug查询
    • 用户主页要按authorId筛选
    • 加上索引后查询速度能提升好几倍

    运行migration:
    • npx prisma migrate dev --name init
    • 创建数据库表结构

    配置Prisma Client单例模式:
    • 在lib/prisma.ts中实现全局单例
    • 避免开发环境热重载时创建过多连接
    • 防止"Too many connections"错误
  3. 3

    步骤3: 实现Server Actions核心功能

    创建Server Actions文件:
    • 在app/actions/post-actions.ts中定义createPost函数
    • 函数前加'use server'指令

    数据验证:
    • 使用Zod定义PostSchema(title、content、slug的验证规则)
    • 用PostSchema.safeParse验证formData数据

    数据库操作:
    • 使用prisma.post.create创建文章
    • authorId从session获取(实际项目中)

    缓存更新:
    • 使用revalidatePath('/blog')重新验证缓存
    • 让新文章立即显示在列表页

    组件调用:
    • 在表单组件中直接使用action={createPost}
    • 不需要useState、fetch、onSubmit事件处理
    • Next.js自动处理序列化、网络请求、错误处理

    Server Actions的优势:
    • 代码量减少30%
    • 不需要写API Routes
    • 开发效率大幅提升
  4. 4

    步骤4: 配置用户认证系统

    安装NextAuth.js:
    • 已通过npm install next-auth安装

    创建认证路由:
    • 在app/api/auth/[...nextauth]/route.ts中配置NextAuth

    配置GitHub OAuth:
    • 在GitHub Developer Settings创建应用
    • 获取Client ID和Secret

    配置Prisma Adapter:
    • 使用PrismaAdapter(prisma)连接数据库
    • 自动创建User、Account、Session等表

    配置providers:
    • 添加GitHubProvider
    • 填入GITHUB_ID和GITHUB_SECRET环境变量

    导出handler:
    • export { handler as GET, handler as POST }

    整个过程10分钟搞定,比自己写JWT认证省事太多
  5. 5

    步骤5: 优化SSR/SSG渲染策略

    博客列表页使用SSG+ISR:在app/blog/page.tsx中设置export const revalidate = 3600(每小时重新生成一次),使用prisma.post.findMany查询已发布的文章,按createdAt降序排列。这个页面在构建时就生成静态HTML,之后每小时自动重新生成,用户访问时直接拿静态文件,加载时间约200ms。博客详情页使用动态SSR:在app/blog/[slug]/page.tsx中每次访问都查数据库拿最新内容,使用prisma.post.findUnique({ where: { slug: params.slug } })查询,适合经常更新的文章,加载时间约800ms。性能对比:SSG页面~200ms,SSR页面~800ms,纯CSR~1500ms,差距一目了然。
  6. 6

    步骤6: 部署到Vercel并优化

    推送代码到GitHub:将项目代码推送到GitHub仓库。在Vercel导入项目:直接在Vercel导入GitHub仓库,Vercel检测到是Next.js项目自动配置好一切。配置环境变量:在Vercel项目设置中添加DATABASE_URL(生产数据库连接)、GITHUB_ID、GITHUB_SECRET、NEXTAUTH_URL(https://your-domain.vercel.app)、NEXTAUTH_SECRET(随机字符串)。生产数据库推荐使用Supabase免费PostgreSQL(每月500MB额度,个人博客完全够用)。Prisma连接池配置:在prisma/schema.prisma的datasource中添加directUrl = env("DIRECT_URL"),Serverless环境下每个函数调用都可能创建新连接,设置directUrl可以复用连接池。图片优化:使用Next.js的Image组件,自动转换成WebP格式,按需加载,性能提升明显。点击Deploy后约2分钟网站上线,最终Lighthouse性能分:桌面端96分,移动端92分,SEO 100分。

常见问题

Next.js 15的Server Actions和API Routes有什么区别?什么时候用哪个?
Server Actions就像"点外卖直送",API Routes是"自己去餐厅取"。前者方便,后者灵活。

Server Actions的优势:
1) 代码量减少30%,不需要写API Routes
2) 直接在组件里调用,不需要useState、fetch、onSubmit事件处理
3) Next.js自动处理序列化、网络请求、错误处理
4) 类型安全,可以直接使用TypeScript类型

使用示例:在函数前加'use server',然后直接在组件里调用(<form action={createPost}>)。

API Routes的优势:
• 更灵活,可以处理复杂的请求逻辑
• 支持中间件
• 适合需要自定义HTTP响应的场景

大部分场景下,Server Actions够用了,只有在需要复杂HTTP处理时才用API Routes。
Turbopack的性能提升有多大?实际使用体验如何?
Next.js 15把Turbopack从实验性变成了稳定版。

官方数据:
• 本地服务器启动快76.7%
• 代码更新快96.3%

实际使用体验:
• 我的项目大概有30多个组件,用Webpack的话启动要7-8秒,Turbopack直接压缩到2秒以内
• 改个代码,热更新几乎是瞬间完成
• 这对开发体验的提升,不是一点半点

Turbopack是Rust写的,比Webpack快很多,特别是在大型项目中优势更明显。如果你还在用Webpack,强烈建议升级到Next.js 15体验Turbopack。
Prisma Client单例模式为什么重要?不配置会有什么问题?
Prisma Client单例模式是Prisma官方推荐的最佳实践。

问题场景:
• Next.js开发环境会热重载,每次重载都创建新的Prisma Client实例
• 连接池很快就爆了,导致"Too many connections"错误
• 我第一次部署到Vercel的时候完全忘了配置这个,结果网站跑了半天就报这个错误,吓得我以为被DDoS攻击了

正确配置:
• 在lib/prisma.ts中实现全局单例:
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient | undefined };
export const prisma = globalForPrisma.prisma ?? new PrismaClient();
if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = prisma;
}

这段代码保证了开发环境下只有一个Prisma实例,生产环境不受影响。记住了,这是Prisma官方推荐的最佳实践!
SSG、SSR、ISR有什么区别?如何选择?
SSG(Static Site Generation):
• 构建时生成静态HTML,速度最快(~200ms)
• 适合内容不经常变化的页面(如博客列表页、关于页面)

SSR(Server-Side Rendering):
• 每次请求时在服务器生成HTML
• 适合需要实时数据的页面(如博客详情页、用户主页)
• 加载时间约800ms

ISR(Incremental Static Regeneration):
• SSG+定时重新生成,结合了SSG的速度和SSR的灵活性
• 适合内容偶尔更新的页面(如博客列表页每小时更新一次)

纯CSR(Client-Side Rendering):
• 在浏览器渲染,SEO差,加载时间~1500ms
• 不推荐用于博客

选择策略:
• 博客列表页用SSG+ISR(export const revalidate = 3600)
• 博客详情页用动态SSR
• 关于页面用纯SSG

性能对比:SSG~200ms,SSR~800ms,纯CSR~1500ms,差距一目了然。
为什么选择PostgreSQL而不是MongoDB?Prisma对PostgreSQL的支持如何?
选择PostgreSQL的原因:
1) Prisma对PostgreSQL的支持更好,类型安全、迁移工具、查询优化都很完善
2) 关系型数据库在处理博客文章、用户、评论这种关系明确的数据时,反而更合适
3) PostgreSQL的全文搜索功能强大,适合博客搜索场景
4) 生产环境稳定性更好,事务支持完善

Prisma的优势:
• 直接从schema生成TypeScript类型,写代码的时候有完整的智能提示,基本不会出错
• 我以前用过Mongoose写MongoDB,类型定义全靠手动维护,一不小心就出bug
• Prisma的类型安全特性让我写代码特别有安全感

如果你需要处理复杂的关系数据,PostgreSQL+Prisma是很好的选择。
Vercel部署Next.js项目需要注意什么?生产环境如何优化?
Vercel部署流程:
1) 推送代码到GitHub
2) 在Vercel导入GitHub仓库,Vercel检测到是Next.js项目自动配置好一切
3) 配置环境变量(DATABASE_URL、GITHUB_ID、GITHUB_SECRET、NEXTAUTH_URL、NEXTAUTH_SECRET)
4) 点击Deploy,约2分钟网站上线

生产环境优化:

1) Prisma连接池配置:
• 在prisma/schema.prisma的datasource中添加directUrl = env("DIRECT_URL")
• Serverless环境下每个函数调用都可能创建新连接,设置directUrl可以复用连接池

2) 图片优化:
• 使用Next.js的Image组件,自动转换成WebP格式,按需加载,性能提升明显

3) 生产数据库推荐使用Supabase免费PostgreSQL(每月500MB额度,个人博客完全够用)

最终性能评分:
• 我用Lighthouse跑了一下,桌面端性能96分,移动端92分,SEO 100分
• 看到这个结果时,真的很有成就感——两天时间,从零到上线,还是生产级的性能

13 分钟阅读 · 发布于: 2025年11月24日 · 修改于: 2026年1月22日

评论

使用 GitHub 账号登录后即可评论

相关文章