当前位置: 首页 > news >正文

进阶篇一 Nuxt4 SSR 原理:服务端渲染到底做了什么

文章目录

    • 一、什么是 SSR
    • 二、Nuxt SSR 流程
    • 三、服务端渲染过程
      • 1. 路由匹配
      • 2. 执行 asyncData
      • 3. 渲染组件
      • 4. 生成完整页面
    • 四、Hydration 是什么
      • Hydration 过程:
      • Hydration 不匹配错误
    • 五、数据传递机制
    • 六、只在客户端执行
    • 七、只在服务端执行
    • 八、服务端上下文
    • 九、SSR 的代价
    • 十、调试 SSR
    • 总结

面试经常被问:“说说 SSR 的原理”。很多人只能答出"在服务端渲染页面",但具体怎么渲染、数据怎么传递、hydration 是什么……一问三不知。今天我们来彻底搞懂 SSR。

一、什么是 SSR

SSR(Server-Side Rendering),服务端渲染。简单说:页面在服务器生成 HTML,浏览器直接显示

对比 CSR(Client-Side Rendering):

CSR 流程: 1. 浏览器请求页面 2. 服务器返回空 HTML + JS 3. 浏览器下载执行 JS 4. JS 请求数据 5. JS 渲染页面 SSR 流程: 1. 浏览器请求页面 2. 服务器执行 JS 获取数据 3. 服务器渲染 HTML 4. 返回完整 HTML 5. 浏览器直接显示

SSR 的好处:

  • 首屏快:不需要等 JS 执行
  • SEO 友好:爬虫能直接看到内容
  • 社交分享:能正确抓取 meta 信息

二、Nuxt SSR 流程

Nuxt 的 SSR 流程更复杂一些:

┌─────────────┐ │ Browser │ └──────┬──────┘ │ 1. 请求页面 ▼ ┌─────────────┐ │ Nuxt Server │ ──> 2. 匹配路由 │ (Nitro) │ ──> 3. 执行中间件 └──────┬──────┘ ──> 4. 执行 asyncData │ 5. 渲染 Vue 组件 │ 6. 返回 HTML ▼ ┌─────────────┐ │ Browser │ ──> 7. 显示 HTML └──────┬──────┘ ──> 8. 加载 JS │ 9. Hydration ▼ ┌─────────────┐ │ Interactive │ ──> 10. 页面可交互 └─────────────┘

三、服务端渲染过程

当用户访问/article/123时:

1. 路由匹配

Nuxt 根据请求路径匹配对应的页面组件:

// 请求 /article/123// 匹配 pages/article/[id].vue

2. 执行 asyncData

在服务端执行数据获取:

<script setup lang="ts"> const route = useRoute() const { data: article } = await useFetch(`/api/articles/${route.params.id}`) </script>

useFetch在服务端会真实发起请求,获取数据。

3. 渲染组件

Vue 将组件渲染成 HTML 字符串:

<article><h1>文章标题</h1><p>文章内容...</p></article>

4. 生成完整页面

Nuxt 将组件 HTML 和数据打包成完整页面:

<!DOCTYPEhtml><html><head><title>文章详情</title><!-- 样式、脚本 --></head><body><divid="__nuxt"><article><h1>文章标题</h1><p>文章内容...</p></article></div><!-- 关键:数据注入 --><script>window.__NUXT__={data:{article:{id:123,title:'文章标题',...}}}</script></body></html>

四、Hydration 是什么

Hydration(水合)是 SSR 的关键步骤:

服务端返回的是:静态 HTML(没有事件绑定) Hydration 做的是:给静态 HTML "注水",让它变成可交互的 Vue 应用

Hydration 过程:

  1. 浏览器加载 Vue 运行时
  2. Vue 根据window.__NUXT__恢复状态
  3. Vue 将事件绑定到已有 DOM 上
  4. 页面变得可交互
<template> <!-- 服务端渲染时:生成静态 HTML --> <button @click="count++">{{ count }}</button> <!-- Hydration 后:点击事件生效 --> </template>

Hydration 不匹配错误

如果服务端渲染的 HTML 和客户端预期的不一样,会报错:

[Vue warn]: Hydration node mismatch

常见原因:

<script setup lang="ts"> // ❌ 服务端和客户端时间不同 const time = new Date().toLocaleString() // ❌ 服务端没有 localStorage const theme = localStorage.getItem('theme') // ❌ 随机值每次不同 const random = Math.random() </script>

解决方法:

<script setup lang="ts"> // ✅ 用 onMounted 处理客户端特有逻辑 const time = ref('') onMounted(() => { time.value = new Date().toLocaleString() }) // ✅ 判断环境 const theme = ref('light') if (import.meta.client) { theme.value = localStorage.getItem('theme') || 'light' } </script>

五、数据传递机制

服务端获取的数据如何传给客户端?

Nuxt 使用window.__NUXT__对象:

<!-- 服务端注入的数据 --><script>window.__NUXT__={serverRendered:true,data:{// useFetch 获取的数据'/api/articles/123':{id:123,title:'...'}},state:{// useState 的状态user:{id:1,name:'...'}}}</script>

客户端初始化时直接使用这些数据,不再重复请求。

六、只在客户端执行

有些代码不需要在服务端执行:

<script setup lang="ts"> // 方式一:onMounted onMounted(() => { console.log('只在客户端执行') }) // 方式二:判断环境 if (import.meta.client) { console.log('只在客户端执行') } // 方式三:ClientOnly 组件(模板中) </script> <template> <ClientOnly> <div>这部分不会在服务端渲染</div> </ClientOnly> </template>

七、只在服务端执行

有些代码只需要在服务端执行:

<script setup lang="ts"> if (import.meta.server) { // 访问数据库、读取文件系统等 const event = useRequestEvent() const headers = getHeaders(event) console.log('请求头:', headers) } </script>

八、服务端上下文

在服务端可以访问请求信息:

<script setup lang="ts"> if (import.meta.server) { const event = useRequestEvent() // 请求 URL const url = getRequestURL(event) // 请求头 const headers = getHeaders(event) // Cookie const cookies = parseCookies(event) // 客户端 IP const ip = getRequestIP(event) // 请求方法 const method = getMethod(event) } </script>

九、SSR 的代价

SSR 不是银弹,有代价:

优点缺点
首屏快服务器压力大
SEO 友好开发复杂度高
社交分享需要处理 Hydration
不能用浏览器特有的 API

选择建议:

  • 内容网站、博客、电商 → SSR
  • 后台管理、工具应用 → CSR
  • 两者结合 → 部分页面 SSR

十、调试 SSR

查看服务端渲染结果:

// 在页面中console.log('服务端渲染:',import.meta.server)console.log('客户端渲染:',import.meta.client)

在终端看到的就是服务端输出,在浏览器控制台看到的是客户端输出。

总结

SSR 核心概念:

概念说明
服务端渲染在服务器生成 HTML
Hydration给静态 HTML 绑定事件
__NUXT__数据传递载体
import.meta.server判断服务端环境
import.meta.client判断客户端环境

理解 SSR 原理,才能写出正确的代码,避免 Hydration 错误。下一篇聊聊渲染模式选择。

相关文章

入门篇三:Nuxt4组件自动导入:写代码少敲一半字

入门篇二:Nuxt 4路由自动生成:告别手动配置路由的日子

延伸阅读

nuxt4完整系列,持续更新中。。,欢迎来逛逛


内容有帮助?点赞、收藏、关注三连!评论区等你 💪

http://www.jsqmd.com/news/647092/

相关文章:

  • 手把手教你用微信云托管绕过域名备案,快速上线小程序后端服务
  • 基于Matlab的矩形波导TE10模电磁场动态可视化实现
  • 算法小记5 二分答案+差分 - whisper
  • MyBatis批量插入数据避坑指南:如何避免TDS协议流参数过多错误
  • 使用 Apache Fesod 读写 Excel
  • 我把Claude Code泄露的代码改造成python程序了,其中的大模型记忆模块与上下文工程分析
  • [特殊字符]Openclaw 梦境(Dream)系统详细研究
  • Adobe-GenP通用补丁:如何安全高效地解锁Adobe全家桶功能
  • opencode 配置本地ollama模型编程
  • 从零到一:基于STM32的L298N电机驱动与PWM调速实战
  • 2026深度分析罗兰艺境市场研究专业服务GEO技术案例,测评北京市场调研公司优化过程与效果验证 - 罗兰艺境GEO
  • 互补PWM死区时间如何根据MOSFET开关参数精确计算?
  • 职场里,越亲近越好?怎样的边界感,才是舒服关系?
  • mysql大表数据清理的利器_使用表分区按天删除数据
  • HTML5 Input 类型详解
  • 新都区急着入住怎么快又好?2026高效靠谱、工期准时的装修公司终极推荐! - 推荐官
  • 【MATLAB实战】手把手教你设计超前校正:从原理到代码实现
  • 渗透测试不够用?红蓝对抗如何精准击穿企业安全体系的深层弱点
  • 大麦抢票脚本终极教程:5分钟学会自动化抢票技巧
  • package.json resolutions:从依赖冲突到版本锁定的实战指南
  • 春茶季,教你一眼认出茶山上的“紫芽”
  • 从AlphaGo到ChatGPT:聊聊强化学习(RL)是如何成为AI进化‘隐藏引擎’的
  • 5分钟搞定openEuler防火墙放行vsftp:主动/被动模式全解析
  • ribbon--重点笔记
  • 盐城哪家好吃
  • 提升你的编码效率,Claude-Mem 插件带来无缝记忆体验!
  • RS485通信故障排查与优化实践指南
  • 【太奶学IT】【超好理解】神经网络是个啥?我这老太婆给你唠明白
  • Python 并发编程:asyncio vs threading vs multiprocessing
  • MATLAB柱状图进阶:5分钟搞定分组数据+数值标注(附完整代码)