ssg ssr csr

8 阅读4分钟

在面试中回答SSG、SSR、CSR的区别时,需从渲染原理、适用场景、技术实现、性能优化等维度展开,结合实际案例说明。以下是结构化的专业回复:

一、核心概念与渲染原理对比

1. CSR(Client-Side Rendering)

  • 原理
    • 浏览器加载HTML文件(仅含空容器和JS引用),通过JS动态生成DOM。
    • 数据请求在客户端完成(如fetch调用API)。
  • 典型框架:React(Create React App)、Vue CLI默认模式。
  • 优缺点
    • 优点:开发体验好(SPA交互流畅),前后端分离清晰。
    • 缺点:首屏加载慢(需等待JS下载+执行),SEO不友好(搜索引擎爬虫仅看到空HTML)。

2. SSR(Server-Side Rendering)

  • 原理
    • 服务器根据请求动态生成完整HTML(包含预渲染的DOM和数据)。
    • 浏览器直接渲染HTML,JS加载后接管交互(Hydration过程)。
  • 典型框架:Next.js(React)、Nuxt.js(Vue)、Gatsby(React)。
  • 优缺点
    • 优点:首屏加载快(HTML已包含内容),SEO友好,利于社交媒体分享。
    • 缺点:服务器压力大,构建/部署复杂(需Node.js环境)。

3. SSG(Static-Site Generation)

  • 原理
    • 构建时(Build Time)生成静态HTML文件,每个路径对应一个HTML。
    • 部署后直接返回预生成的HTML,无需服务器实时渲染。
  • 典型工具:Next.js(getStaticProps)、Nuxt.js(静态模式)、Hugo、Jekyll。
  • 优缺点
    • 优点:性能极致(静态文件加载最快),成本低(可部署到CDN),SEO友好。
    • 缺点:内容更新需重新构建,不适合实时数据场景。

二、技术实现对比

维度CSRSSRSSG
渲染时机客户端(浏览器)服务器(请求时)构建时(Build Time)
数据获取客户端JS请求API服务器端请求API(如Node.js)构建时请求API(如Next.js的getStaticProps
HTML生成JS动态生成服务器动态渲染构建时预生成静态HTML
交互接管全量JS执行JS执行后Hydrate已有DOMJS执行后Hydrate已有DOM
部署方式静态文件服务器(如Nginx)Node.js服务器(如Vercel)静态文件服务器/CDN(如Netlify)

三、适用场景与选型策略

1. 按业务场景选择

  • CSR

    • 适合内部管理系统(无需SEO)、纯客户端交互应用(如游戏)。
    • 示例:React Admin Dashboard、Figma类工具。
  • SSR

    • 适合内容需要SEO(如电商商品页、新闻网站)且实时更新频繁。
    • 示例:Netflix电影详情页(实时推荐)、Medium文章页。
  • SSG

    • 适合内容更新频率低但访问量大的场景(如博客、文档、营销页)。
    • 示例:GitHub Pages文档、电商促销活动页、企业官网。

2. 按性能需求选择

指标CSRSSRSSG
首屏加载(FCP)最慢较快最快
TTFB(Time to First Byte)快(静态文件)较慢(服务器处理)极快(CDN直接返回)
SEO友好度
服务器成本低(静态文件)高(需Node.js)极低(CDN)

四、关键技术细节(面试加分项)

1. SSR的Hydration过程

  • 定义:服务器渲染的HTML与客户端JS逻辑“衔接”的过程。
  • 关键步骤
    1. 浏览器解析服务器返回的HTML,显示预渲染内容。
    2. 客户端JS加载后,React/Vue等框架比对已有DOM结构,绑定事件处理函数。
  • 优化点
    • 避免服务器和客户端生成的HTML不一致(如日期格式化差异),否则触发DOM重绘。

2. SSG的增量静态再生(ISR)

  • Next.js实现
    export async function getStaticProps() {
      return {
        props: { data },
        revalidate: 60 // 60秒后允许重新生成页面
      }
    }
    
  • 优势:结合SSG的性能与动态内容更新能力,适合内容有一定时效性的场景(如新闻列表)。

3. CSR的SEO方案

  • SSR降级方案
    • 使用无头浏览器(如Puppeteer)在爬虫访问时生成临时HTML:
      // Node.js中间件示例
      app.get('*', async (req, res) => {
        if (isBot(req.headers['user-agent'])) {
          const html = await renderWithPuppeteer(req.url);
          res.send(html);
        } else {
          res.sendFile(path.join(__dirname, 'public/index.html'));
        }
      });
      
    • 服务成本高,仅适合核心页面。

五、实战案例与优化经验

案例1:电商网站商品页(从CSR到SSR)

  • 问题:商品页SEO差,首屏加载需2秒(JS+数据请求)。
  • 方案
    • 迁移至Next.js,使用getServerSideProps在服务器获取商品数据并渲染HTML。
    • 图片懒加载,非首屏内容(如评论区)改为客户端渲染。
  • 效果:SEO流量提升30%,FCP从2秒降至0.8秒。

案例2:博客网站(从CSR到SSG)

  • 问题:博客文章多(500+页),CSR首屏慢,服务器成本高。
  • 方案
    • 使用Next.js的getStaticPaths+getStaticProps在构建时生成所有文章页。
    • 部署到Vercel,利用CDN全球分发。
  • 效果:单篇文章加载时间从1.5秒降至0.3秒,服务器成本节省80%。

六、总结与延伸思考

选型口诀:

静态内容选SSG,实时内容选SSR,交互优先选CSR,混合场景用混合渲染

未来趋势:

  • 混合渲染(Hybrid Rendering):同一应用中不同路由使用不同渲染模式(如Next.js支持getServerSidePropsgetStaticProps共存)。
  • 边缘计算(Edge SSR):在CDN节点执行SSR,降低延迟(如Vercel Edge Functions)。