我如何用 Next.js 与 Supabase 将我的 AI 图像应用从 3 秒优化到 300 毫秒

发布: (2026年1月8日 GMT+8 16:02)
3 min read
原文: Dev.to

Source: Dev.to

Hello Developers! 👋

我最近发布了 Nanobanan Editor,这是一款基于 AI、可以通过自然语言提示进行图像编辑的工具。虽然 MVP 的开发过程很有趣,但 Community Feed 页面加载需要 3–5 秒,这成为了我必须解决的性能问题。

下面是我如何诊断瓶颈并将加载时间降至 300 毫秒以下(提升 10 倍)的过程,主要使用了客户端渲染策略和数据库索引。

The Stack 🛠️

  • 框架:Next.js 14(App Router)
  • 数据库:Supabase(PostgreSQL)
  • 样式:TailwindCSS
  • 部署:Vercel

The Problem: Traditional SSR Bloat 🐢

最初,社区页面使用标准的服务器端渲染(SSR):

// ❌ The slow way (Simplified)
export const dynamic = "force-dynamic";

export default async function CommunityPage() {
  // Blocking current thread to fetch database
  const images = await supabase.from('generations').select('*')...;

  return ;
}

为什么慢

  • 阻塞 —— 在数据库查询完成之前,HTML 不会流式输出。
  • 复杂查询 —— 大数据集上没有合适的索引。
  • 网络延迟 —— 每次请求都要进行一次服务器到数据库的往返。

The Solution: CSR + SWR + Indexes 🚀

我改用了客户端渲染(CSR)并结合 Stale‑While‑Revalidate(SWR)策略,同时为数据库添加了必要的索引。

Step 1: Switch to CSR with Skeleton Loading

先展示 UI 骨架,再在后台获取数据。

"use client";
import useSWR from "swr";

export default function CommunityPage() {
  // Non‑blocking fetch
  const { data, isLoading } = useSWR("/api/community/feed", fetcher);

  if (isLoading) return ; // Instant feedback

  return ;
}

Step 2: Intelligent Caching with SWR

缓存响应,这样快速回访时就不会再次请求 API。

const { data } = useSWR("/api/community/feed", fetcher, {
  dedupingInterval: 60_000, // Reuse data for 60 s
  revalidateOnFocus: false, // No refetch just because the tab gains focus
});

Step 3: Database Indexing (The Real MVP)

原始查询会进行顺序扫描:

SELECT * FROM generations
WHERE is_public = true
ORDER BY created_at DESC
LIMIT 12;

添加复合索引后问题得到解决:

CREATE INDEX idx_generations_public_created
ON generations (is_public, created_at DESC)
WHERE is_public = true;

查询时间从 ≈ 500 ms 降至 ≈ 15 ms

Results 📊

  • 首次加载:约 300 ms(骨架 UI 立即出现)
  • 再次访问:< 50 ms(命中缓存)
  • Lighthouse 分数:从 65 提升到 95

Try It Out

现场体验速度差异:

👉 Nanobanan Editor Community

社区动态截图

这段经历表明,虽然 SSR 功能强大,但通过精心设计的 CSR、智能缓存以及恰当的索引,完全可以为基于动态列表的页面提供更流畅的用户体验。如有关于 Next.js + Supabase 组合的任何问题,欢迎在评论区提问!

Back to Blog

相关文章

阅读更多 »

Rapg:基于 TUI 的密钥管理器

我们都有这种经历。你加入一个新项目,首先听到的就是:“在 Slack 的置顶消息里查找 .env 文件”。或者你有多个 .env …

技术是赋能者,而非救世主

为什么思考的清晰度比你使用的工具更重要。Technology 常被视为一种魔法开关——只要打开,它就能让一切改善。新的 software,...

踏入 agentic coding

使用 Copilot Agent 的经验 我主要使用 GitHub Copilot 进行 inline edits 和 PR reviews,让我的大脑完成大部分思考。最近我决定 t...