起因
新项目要选前端 SSR framework。两个主流:
- Next.js(React,Vercel):业界事实标准
- SvelteKit(Svelte,Vercel):更小 bundle,更直觉
最近用 SvelteKit 做一个新项目,Next.js 维护两个老项目。下面对比。
文件结构
Next.js(app router):
app/
layout.tsx
page.tsx
blog/
[slug]/
page.tsx # /blog/:slug
api/
posts/route.ts # GET/POST /api/posts
SvelteKit:
src/routes/
+layout.svelte
+page.svelte # /
blog/
[slug]/
+page.svelte # /blog/:slug
+page.server.ts # server-side load
api/
posts/+server.ts # GET/POST /api/posts
类似的 file-based routing,约定不同。
写法对比
// Next.js page
export default async function Page({ params }: { params: { slug: string } }) {
const post = await db.posts.findFirst({ where: { slug: params.slug } });
return (
<article>
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.body }} />
</article>
);
}
<!-- SvelteKit +page.svelte -->
<script lang="ts">
export let data; // 从 +page.server.ts load 函数来
let { post } = data;
</script>
<article>
<h1>{post.title}</h1>
{@html post.body}
</article>
// +page.server.ts
export async function load({ params }) {
const post = await db.posts.findFirst({ where: { slug: params.slug } });
return { post };
}
SvelteKit 强制分离 server load 跟 view,Next.js app router 同 file
(async component)。
SvelteKit 模板语法更接近 HTML({@html} {#if} {#each})。
React 是 JS-first(JSX)。
bundle size
baseline blank page:
- Next.js: ~85 KB JS(React runtime + Next router)
- SvelteKit: ~10 KB JS(Svelte compile 到 vanilla JS)
Svelte 是编译时框架,runtime 极小。
React 是 runtime 框架,最小也几十 KB。
实际复杂 app:
- Next.js: 200-500 KB
- SvelteKit: 50-200 KB
老旧移动设备 / 网络差地区差异显著。
性能
SSR / 静态生成性能两者接近(看 hosting / CDN)。
客户端 hydration:
- React: ~150ms typical page
- Svelte: ~30ms
Svelte 编译时已生成 DOM 更新代码,hydration 简单。
React 要重新跑 component tree 对比 virtual DOM。
state 管理
React:useState / useReducer / Zustand / Redux / Jotai 等。
Svelte 5(runes):
<script>
let count = $state(0);
let doubled = $derived(count * 2);
$effect(() => {
console.log(`count: ${count}`);
});
</script>
<button on:click={() => count++}>+1</button>
<p>doubled: {doubled}</p>
$state / $derived / $effect 内置 reactive primitive。
不需要库。
跨组件用 store:
// stores.ts
import { writable } from 'svelte/store';
export const user = writable(null);
// 组件
import { user } from './stores';
$user // 自动 subscribe
React 同样需求要 Zustand / Jotai / Context。
ecosystem
| Next.js | SvelteKit | |
|---|---|---|
| UI 库 | 极多(Material / Chakra / shadcn 等等) | 中(Skeleton / SVeltestrap / shadcn-svelte) |
| component snippets | 几万 | 几千 |
| 招聘 React | 海量 | 中 |
| 第三方教程 | 海量 | 中 |
| Vercel / 部署 | 一等公民 | 一等公民 |
React 生态优势大。
部署
两者都 Vercel friendly(一键 git push 部署)。
Cloudflare Pages / Netlify / 自托管也都 OK。
SvelteKit 的 adapter 概念:同 codebase 部署到不同 platform:
// svelte.config.js
import adapter from '@sveltejs/adapter-cloudflare'; // or node / vercel / netlify
export default {
kit: { adapter: adapter() },
};
Next.js 也行但 vendor lock 严重些。
学习曲线
Svelte 新人:HTML + JS 像,3-5 天上手。
React 新人:JSX + hook 概念多,1-2 周上手。
但 React 后续生态 / TypeScript 集成成熟,深入资料无限。
Svelte 5 runes 是新(2024)变化大,老教程过时。
实战 case:从 React 迁 Svelte
我们一个内部 admin tool 原 React (CRA),bundle 800KB。
迁 SvelteKit:
- 3 周重写
- bundle 180KB
- 加载快 2-3x
- 代码行数 -40%
主要节省:
- 不用 useEffect 注意 dep array
- 表单写法简洁(bind:value)
- 不用 Redux(store 几行)
但缺点:
- 团队学习
- 某些 React 专用库(react-flow 之类)没 Svelte 等价 → 自己写或者用 web component
React 仍胜的场景
- 大型团队 / 已有 React 经验
- React Native 共享 UI
- 极丰富的第三方组件依赖
- Server Components(React 19+)+ Next.js 强大
SvelteKit 仍胜的场景
- 性能 critical(移动 / 老设备)
- 小团队 + 偏 web 标准
- 内容站 / 静态化重 + SSR
- 想少写代码
部署一个 demo
npm create svelte@latest my-app
cd my-app && npm install
npm run dev # localhost:5173
npx create-next-app@latest my-app
cd my-app && npm run dev # localhost:3000
两个都 5 分钟跑起来。
与其它框架对比
- Astro:内容站王者,多框架混用,islands 架构。SSR 比 Next / SvelteKit 简单
- Nuxt(Vue):Vue 圈的 Next,类似哲学
- SolidStart:Solid.js 的 framework,性能极好
- Remix:React 路线,更"web 标准 first"(已并入 React Router 7)
新项目 2026 视角:
- 内容站 → Astro
- 应用 + 团队 React → Next.js
- 应用 + 性能 / 简洁 → SvelteKit
- 应用 + Vue 团队 → Nuxt
踩过的坑
-
SvelteKit prerender 错配:以为静态生成,结果运行时还跑 → 用
export const prerender = true显式标记。 -
server-only code 漏到 client:API key 写在 +page.svelte 里 →
bundle 到 client。server code 放 +page.server.ts / +server.ts。 -
Next.js app router 学习陡:server components / client components
边界要清。误用 hook 报错难懂。 -
Svelte 5 vs 4 转换:runes 是新,老 reactive
let count = 0; $: doubled = count * 2仍兼容但官方推 runes。教程乱。 -
TypeScript 集成:SvelteKit 比 Next 略弱(template 内的类型推断)。
严格项目要小心。
登录后参与评论。