Next.js 不是默认答案:我的前端框架选型思路

2026-11-07 · 开发

新建项目的时候,手已经习惯性敲出 create-next-app 了。 但我最近开的三个项目都没有用它。 不是因为它不好,而是因为它擅长解决的问题,恰好不是我要解决的问题。

先问三个问题,再谈框架

选框架之前,我更愿意先把这三件事定下来。它们比「哪个框架更流行」重要得多, 而且一旦定了,候选范围会自己缩小。

  1. 首屏内容需不需要被搜索引擎和分享卡片抓到?
  2. 第一屏渲染出来的东西,是不是每个人都一样?
  3. 部署环境允许什么——只放静态文件,还是可以有常驻的 Node 进程?

三个答案基本决定了渲染模式,而渲染模式基本决定了框架。 很多人反过来做——先选框架,再想办法把需求塞进去,最后在构建配置和缓存上面花掉大把时间。

四种形态,四种选择

形态典型场景渲染模式我会选
纯内容 博客、文档、产品落地页 构建期静态生成 Astro,或者干脆手写 HTML
营销站 + 动态数据 首屏要个性化、又要被收录 SSR / ISR Next.js(App Router)
后台与内部工具 登录后才看得到的数据表格 客户端渲染 Vite + React Router
交互密集的小应用 编辑器、看板、实时面板 客户端为主,必要时补 SSR SvelteKit

Next.js:强,但复杂度是要付账的

App Router 那套服务端组件加流式渲染确实强, 它把「数据在服务端取,UI 在客户端流式到达」变成了一件顺手的事。 但代价是:「这段代码在哪里执行」从一件不用想的事,变成了要一直想的事。

一个文件是 Server Component 还是 Client Component,决定了它能不能用 useState、 能不能直接读数据库、能不能拿到 window。 我见过不少项目,一半的沟通成本花在「这个组件为什么会报 hooks 错误」上。

另外两处需要提前想清楚的地方:

这些都不是缺点,是复杂度税。 当项目确实需要 SSR/ISR、也确实从中受益时,这笔税值得交; 当你只是需要一个三页的后台表格时,就是白交。

Astro:内容站的默认赢家

默认输出零 JavaScript,交互组件作为「岛」按需水合。 Markdown 进去、HTML 出来,构建产物就是一堆静态文件,扔给任何 nginx 都能跑。 博客、文档、落地页这类场景,它几乎没什么可挑的。

但它的优势来自「没有交互」。一旦页面上出现拖拽、实时筛选、复杂的表单联动, 岛与岛之间的状态共享就变得别扭,反而不如一开始就上 React。

Vite + React:后台工具的最优解

心智负担最低的一档:一个 index.html、一个入口文件, 构建产物是一堆静态资源。没有服务端渲染、没有运行时、没有缓存策略。

代价是路由、数据请求、鉴权拦截这些要自己补一遍。 但对后台来说,这些代价换来的东西根本用不上—— 用户登录之后才进来,不需要被搜索引擎收录,首屏白几百毫秒也无所谓。 为了一个内部表格引入 SSR,是我这几年做过最没必要的决定之一。

SvelteKit:写起来最舒服,但要考虑协作

响应式和状态是一等公民,同样的界面代码量明显更少,产物也小。 自己一个人做小应用时,它的开发体验是最好的。

需要权衡的是生态和人力:遇到冷门问题时答案更少, 团队里会用的人也更少。如果是长期多人维护的项目,这一条要算进去。

这个站点为什么是手写 HTML

十来个静态页面、零构建、零依赖。改一篇文章就是改一个文件, 传上去就生效,不需要 npm install, 也不会某天因为某个依赖的主版本升级导致构建失败。

它没用任何框架,不是因为框架不好,而是因为它的复杂度还没到需要框架的程度。 引入框架是为了解决「组件复用和状态管理」,而这个站点没有状态。

反过来说,如果哪天我要在这里加全文搜索、分页、或者几十篇文章, 我会先换 Astro —— 它能在保持「产物是静态 HTML」的前提下, 把重复的布局抽成组件。这个方向是对的:先保证产物形态不变,再谈工具升级。

两个实际踩过的坑

1. 把只读后台塞进 SSR 框架

那个后台一共三个页面,数据来自两个只读接口。 用了 SSR 框架之后,多了一个常驻进程、一套部署脚本, 还有一堆「为什么服务端渲染时拿不到 window」的问题。 最后换成 Vite 打包的静态文件,部署从「构建 + 重启服务」变成「覆盖一个目录」。

2. 在内容站上用了 SPA

首屏要等 JS 下载并执行完才出现内容,分享到聊天软件里没有摘要卡片, 搜索引擎抓到的几乎是一个空壳。改成构建期生成之后再没管过, 问题不是被优化掉的,是根本不存在了。

结论

先定渲染模式,再定部署形态,最后才选框架。 框架是可替换的,形态不是。

三五年后想换框架,只要产物还是「静态文件 + 一层接口」, 换起来大概是一周的事;但如果形态错了—— 该静态的做成了 SSR、该 SSR 的做成了纯客户端—— 换什么框架都救不回来。

所以现在我的默认动作不是敲 create-next-app, 而是先把上面那三个问题的答案写下来。写完之后,选型往往只剩一个候选。

← 返回笔记列表