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

在历史项目升级中用SSR和SSG优化性能的实现流程

核心目标: 让用户第一次打开页面时,看到内容更快(减少白屏/加载转圈),并且减轻浏览器的负担,从而提升整体性能,尤其是对老项目或者低端设备用户特别友好。

简单理解两者:

  1. SSR (服务端渲染 - Server-Side Rendering):

    • 比喻: 想象你去餐厅点菜。SSR 就是厨房(服务器)把菜(完整的 HTML 页面)完全做好、摆好盘,直接端到你桌上(浏览器)。你坐下就能开吃(看到完整内容)。

    • 关键点: 用户请求页面时,服务器实时运行你的前端代码(React/Vue等),获取数据,生成包含最终内容的 HTML,然后发给浏览器。浏览器下载后,内容已经在了,只需要“激活”交互功能(Hydration)。

  2. SSG (静态站点生成 - Static Site Generation):

    • 比喻: 还是餐厅,但这次是自助餐。厨房(构建过程)在开门营业前(用户访问前) 就把所有可能受欢迎的菜(HTML页面)都提前做好、摆好在餐台上。用户来了,直接拿现成的吃(获取预先生成的静态文件)。

    • 关键点: 在你发布网站时(npm run build),工具会预先运行你的前端代码,获取所有需要的数据,为每一个可能的页面生成纯 HTML、CSS、JS 文件。用户访问时,CDN 直接把这些“成品”文件快速送过去,几乎不需要服务器实时计算。

为什么能优化性能?

  • 首屏速度快: 用户拿到的是包含内容的 HTML,不是空壳子或加载动画。浏览器能立刻渲染内容,用户感觉“秒开”。

  • 减少浏览器压力: 服务器或构建过程承担了组装页面的重活,老旧的用户设备只需要负责显示和简单的交互,负担小很多。

  • 更好的 SEO: 搜索引擎爬虫拿到的是完整的 HTML 内容,更容易理解页面信息。

  • 减轻服务器负担 (SSG): SSG 的页面是纯静态文件,可以被 CDN 高效缓存,服务器只在构建时忙一下,用户访问时几乎零压力。

  • 更稳定的 TTFB (SSG): 静态文件返回速度极快,用户等待服务器响应的第一字节时间大大缩短。

在历史项目中实施的流程 :

假设有一个基于 React 的老项目(Vue/Angular 原理类似),之前是纯 CSR (客户端渲染) - 即浏览器下载一个空壳 HTML 和一堆 JS,然后 JS 再去请求数据、组装页面,导致首屏慢。

步骤 1:选好工具 (架锅烧油)

  • 你需要一个支持 SSR 和 SSG 的框架。最常见的选择:

    • Next.js (React): 目前最流行、最成熟,对 SSR/SSG 支持开箱即用,文档丰富,社区庞大。强烈推荐历史项目迁移使用。

    • Nuxt.js (Vue): Vue 生态的类似方案,同样优秀。

    • Gatsby (React, 更侧重 SSG/数据驱动): 非常适合博客、文档、营销页等偏静态内容。

    • Angular Universal (Angular): Angular 官方的 SSR 解决方案。

  • 选择建议: Next.js/Nuxt.js 通常是最平滑的升级路径,因为它们提供了完整的应用结构和路由方案。

步骤 2:项目改造 (准备食材)

  • 安装依赖: 用 npm/yarn 安装你选择的框架(以Next.js为例,如 npm install next react react-dom)。

  • 调整项目结构:

    • 框架(如 Next.js)有特定的目录约定(如 pages/public/getStaticPropsgetServerSideProps)。你需要把旧项目的页面组件迁移到这些约定目录下。

    • 可能需要拆分组件,把数据获取逻辑从组件内部移到框架提供的方法中。

  • 路由改造:

    • 框架通常有自己基于文件系统的路由(pages/about.js -> /about)。你需要将旧的路由配置(如 React Router)迁移或适配到这个新路由系统。Next.js 的路由基本是自动的,非常省心。

  • 数据获取改造 (最关键!):

    • 识别哪些数据用于渲染页面: 是商品列表?用户信息?文章内容?

    • 决定用 SSR 还是 SSG:

      • SSG (getStaticProps - Next.js 为例): 如果页面内容在构建时就能确定,或者更新频率很低(一天几次),或者可以接受构建后才更新。比如:博客文章、产品介绍页、公司“关于我们”页、营销活动页。在 page 组件文件中导出 async getStaticProps() 函数,在里面获取数据并 return { props: { ... } }。这些数据会在构建时传给组件生成静态 HTML。

      • SSR (getServerSideProps - Next.js 为例): 如果页面内容每次请求都可能不同,或者需要访问请求对象(req/res,比如拿 Cookie 做用户认证),或者数据必须实时性极高(秒级更新)。比如:用户个人中心页、带实时数据的仪表盘、依赖用户登录态的页面。在 page 组件文件中导出 async getServerSideProps(context) 函数,在里面获取数据并 return { props: { ... } }。这个函数在每次用户请求该页面时在服务器运行,生成带数据的 HTML。

      • ISR (增量静态再生 - Next.js 独有, 超好用!): SSG 的升级版。先按 SSG 生成静态页面并缓存。可以设置一个 revalidate 时间(秒)。在 revalidate 时间内访问,直接返回缓存(超快)。过了时间后的第一次访问,后台会重新生成新页面,下次访问用新的;同时这次访问依然返回旧的缓存(用户无感知)。完美平衡速度和新鲜度!非常适合新闻列表、商品列表等。

    • 改造 API 调用: 原来在组件 useEffect 里或组件挂载时发起的 API 请求,要挪到 getStaticProps / getServerSideProps 中去。组件本身变成主要接收 props 来渲染。

  • 处理客户端专有代码 (处理鱼刺):

    • 像访问 windowdocumentlocalStorage 这样的浏览器特有对象,在服务器环境(SSR/SSG 构建时)是不存在的!

    • 需要把这些代码放到:

      • useEffect 钩子中(只在客户端运行)

      • 或者用 if (typeof window !== 'undefined') { ... } 判断

      • 或者动态导入(dynamic import)包含这类代码的组件,并设置 ssr: false (Next.js: dynamic(() => import('...'), { ssr: false }))

步骤 3:构建与部署 (开火烹饪)

  • 开发环境 (npm run dev): 框架会同时支持 CSR、SSR 和 SSG 的开发预览,方便调试。

  • 生产构建 (npm run build - Next.js 为例):

    • 框架会分析你的页面:

      • 标记了 getStaticProps 的页面 -> 走 SSG 流程。在构建阶段调用 getStaticProps,获取数据,为每个页面生成静态 HTML 文件(可能还有 JSON 数据文件)。如果用了动态路由(pages/posts/[id].js),它会根据 getStaticPaths 返回的路径列表生成所有可能的静态页面。

      • 标记了 getServerSideProps 的页面 -> 走 SSR 流程。不生成静态 HTML,但会准备好服务器运行时代码。用户请求时服务器实时渲染。

      • 没标记的页面 -> 默认是 CSR。

    • 生成优化后的 JS/CSS 等静态资源。

  • 部署:

    • SSG 页面: 生成的纯 HTML/CSS/JS 文件可以部署到任何静态托管平台 (Vercel, Netlify, GitHub Pages, AWS S3 + CloudFront 等)。它们通常有全球 CDN,访问速度极快。

    • SSR 页面: 需要部署到一个能运行 Node.js 的服务器环境 (Vercel, Netlify Functions, AWS Lambda, 自己的 Node 服务器,Docker 容器等)。当用户请求 SSR 页面时,这个服务器环境会执行 getServerSideProps 和渲染逻辑。

    • 混合部署 (推荐): 大部分项目都是混合的!首页、博客文章用 SSG/ISR;用户个人中心、搜索页用 SSR。像 Vercel (Next.js 亲爹) 能智能处理:收到请求,如果是 SSG 且有缓存,CDN 直接返回;如果是 SSR 或 SSG 缓存过期(ISR),就调用服务器函数渲染。开发者几乎不用操心。

步骤 4:监控与调优 (尝咸淡,调火候)

  • 性能测试: 用 Lighthouse, WebPageTest 等工具测试升级前后的关键指标:FCP (首次内容绘制), LCP (最大内容绘制), TTI (可交互时间), TTFB (首字节时间)。看优化效果。

  • 分析包大小: 框架的构建输出通常包含分析工具(Next.js: npm run build -- --analyze),查看生成的 JS 包,优化过大的依赖。

  • CDN 配置: 确保静态资源(包括 SSG 页面)设置了合理的缓存头,充分利用 CDN 缓存。

  • ISR 调优: 根据数据更新频率调整 revalidate 时间。对于海量页面,可以用 fallback 模式(getStaticPaths 中返回部分路径,其他路径在首次访问时按需生成并缓存)。

总结一下关键流程:

  1. 选武器: Next.js/Nuxt.js 等框架。

  2. 搬家具: 按框架要求调整项目结构、路由。

  3. 改数据拿法 (核心!):

    • 不变的/更新慢的页面 -> SSG (getStaticProps): 构建时生成好,飞快!

    • 每次访问都变的/需要 req 的页面 -> SSR (getServerSideProps): 服务器实时做,保证新鲜。

    • 想又快又相对新鲜 -> ISR (revalidate): 缓存+后台更新,真香!

  4. 避坑: 把只能在浏览器运行的代码 (windowdocument) 包起来。

  5. 建造&发布: build 命令生成文件,部署到合适的平台(静态托管给 SSG,Node 环境给 SSR)。

  6. 看看效果: 测速、分析、调缓存。

人话精髓:

  • SSG: 提前把页面像做预制菜一样做好存冰箱(CDN),用户点单(访问)直接微波炉加热(快速发送),省时省力速度快!适合内容固定的页面。

  • SSR: 用户点单(访问)后,厨师(服务器)现场开火炒菜(实时获取数据+渲染),保证菜是热的(数据最新),但等菜时间稍长一点。适合内容实时性要求高的页面。

  • 升级关键: 把老项目中“在浏览器里现场炒菜”(CSR)的部分,改成要么“提前做好预制菜”(SSG),要么“让服务器大厨代炒”(SSR)。改造的重点就是怎么拿数据什么时候生成页面

这样改造下来,历史项目就能焕发新生,用户打开速度嗖嗖的,体验提升立竿见影!

ps: 知识学习整理的简单记录,如有不严谨之处,欢迎指正

http://www.xdnf.cn/news/12152.html

相关文章:

  • em/px/rem/vh/vw区别
  • IBMS综合运维平台业务分析与BA楼宇自控系统技术架构与应用
  • Node事件循环机制详解
  • 【QQMusic】在LikePage点击取消喜欢没有反应
  • (LeetCode 每日一题) 1061. 按字典序排列最小的等效字符串 (并查集)
  • 双空间知识蒸馏用于大语言模型
  • Android 本地存储路径说明
  • 创客匠人解密创始人IP打造:知识变现的三大核心逻辑
  • 编程笔记---问题小计
  • 玄机——Linux等保测评
  • 游戏开发中的CI/CD优化案例:知名游戏公司Gearbox使用TeamCity简化CI/CD流程
  • 山东大学深度学习期末概念汇总
  • 音视频之视频压缩编码的基本原理
  • StoreView SQL,让数据分析不受地域限制
  • Java八股文——集合「Map篇」
  • Agentic AI 和 Agent AI 到底区别在哪里?
  • 华为云CentOS配置在线yum源,连接公网后,逐步复制粘贴,看好自己对应的版本即可,【新手必看】
  • [蓝桥杯]螺旋矩阵
  • KMP算法:如何通过 next 数组推导模式串该从哪里继续匹配
  • Vue3解决“找不到模块@/components/xxx.vue或其相应的类型声明ts文件(2307)”
  • 华为云Flexus+DeepSeek征文| 华为云Flexus X实例单机部署Dify-LLM应用开发平台全流程指南
  • Vue ②-computed || watch || 指令
  • oracle数据恢复—oracle数据库执行truncate命令后的怎么恢复数据?
  • deepseek-r1-0528-qwen3-8b本地部署:Ollama老版本大升级至0.9.0
  • Three.js光与影代码分析及原理阐述
  • C++STL-sting类的模拟实现
  • nginx.conf配置详解:从(413 Request Entity Too Large)说起
  • Scrum基础知识以及Scrum和传统瀑布式开发的区别
  • 计算机磁盘旁黄色警示标志消除|BitLocker关闭方法
  • <论文>(微软)WINA:用于加速大语言模型推理的权重感知神经元激活