本文以 ReactVue 为例,介绍下主流的渲染模式以及在主流框架中如何实现上述的渲染模式。

前置知识介绍

看渲染模式之前我们先看下几个主流框架所提供的相关能力,了解的可跳到下个章节。

挂载组件到 DOM 节点

这是主流框架最基本的能力,就是将组件渲染到指定的 DOM 节点上。在 React 中所使用的 APIrender,在 Vue 中所使用的是 createApp 后的 mount

水合

水合用来将组件渲染到已有的静态内容上,用于为静态页面恢复其交互和动态能力。在 React 中所使用的 APIhydrateReact 18 前的版本) 和 createHydrateReact 18),在 Vue 中所使用的是 createSSRApp 后的 mount

Vue 中的 API 语义稍显奇怪,因为使用 createSSRApp 的场景并不一定是 SSR

输出渲染内容

主流框架除了可以将组件渲染到 DOM 节点上以外,还能将其要渲染的内容直接输出为如 HTML 字符串等形式。输出为字符串的 APIReactVue 中所使用的 API 都叫做 renderToString

React 中还推出了很多其它的 API:如 renderToStaticMarkuprenderToStaticNodeStream 等等。功能基本一致,不影响本文的内容所以此处不细说了。下面的例子中仅以 renderToString 为例。

主流渲染模式

知道了主流框架的这几种能力,我们再来通过标题提到的几种主流渲染模式看下他们能用来组合出什么样的效果,

CSR - Client Side Rendering - 客户端渲染

CSR 就是我们常见的 SPA 所使用的渲染方式,所有的主流框架都支持,或者说:只要是在客户端渲染过程中使用到了脚本都可以算作客户端渲染。

CSR 主要流程为:

  1. 浏览器加载页面
  2. 加载对应的脚本
  3. 脚本执行时向页面中渲染内容,此步骤一般包含两种方式:
    1. 向一个空节点中渲染内容,一般应用于纯粹的 CSR 应用。这里使用的就是上面提到的挂载组件的功能。
    2. 向一个已有内容的节点中渲染内容,通常应用于 CSR 与其它渲染模式(SSRSSGISR)结合的场景下

CSR 的使用场景定义也很简单,如果在客户端页面有动态需求或需要交互则必须使用。

SSR - Server Side Rendering - 服务端渲染

SSR 是另一个比较常见的渲染模式,使用这种渲染模式可以从服务端直接返回要渲染的静态内容。

其常见流程为:

  1. 浏览器发起 HTTP 请求对应的页面
  2. 服务端接收到请求后准备渲染页面所需要的数据
  3. 将所需要的数据传入需要渲染的页面组件中然后通过 renderToString 输出为静态内容
  4. 拼接页面模版、水合脚本等将生成的静态内容返回到浏览器,浏览器进行渲染
  5. 浏览器渲染内容,执行水合脚本恢复页面交互和动态能力

纯粹的 SSR 指代的接收到请求、输出静态内容、返回浏览器的模式。水合的相关部分是属于 CSR 的内容。

要注意水合并不是必须的,可以按需选择。比如如果你的需求是要对不同的用户展示不同的页面,然而页面上并没有任何可以交互或动态的内容,那完全可以忽略水合的部分。

SSR 一般应用于以下场景:

  1. 出于首页打开速度、用户体验、SEO 等目的需要让用户更快的看到页面首屏内容
  2. 想要预先渲染的页面内容中存在动态的内容

SSG - Static Site Generation - 静态站点生成

SSG 现在也比较常见,它所指代的是在构建阶段就将页面所需要的数据准备好然后将需要的页面通过脚本构建为静态内容的模式。

其常见流程为:

  1. 在构建阶段构建脚本遍历所有需要静态构建的页面
  2. 获取渲染所需要的数据并通过 renderToString 输出为静态内容
  3. 将静态内容拼接页面模版和水合脚本等内容后保存到文件中
  4. 浏览器发起请求时从服务端返回静态页面(一般直接使用静态文件服务器即可)
  5. 浏览器渲染内容,执行水合脚本恢复页面交互和动态能力

纯粹的 SSG 指代的同样是不包含 CSR 部分的内容,即构建阶段生成静态页面并在请求时直接将静态页面返回的过程。水合过程同样不是必须的,视需求决定即可。

SSG 一般应用于以下场景:

  1. 出于首页打开速度、用户体验、SEO 等目的需要让用户更快的看到页面首屏内容
  2. 页面中基本都是静态内容,变动很少或变动的时机比较固定

所以常用于通过 CMS 生成内容、博客站点等静态内容较多的场景。

ISR - Incremental Static Regeneration - 增量静态再生

ISR 目前使用的不多,它算是 SSG 的一种增强版,指的是在 SSG 的基础上,服务端在收到页面请求时会对页面的时效性进行判断,如果认定失效则会对该页面进行增量构建的一种模式。

其常见的流程如下:

可以看出 ISR 在构建和客户端环节没有任何的变化,而是增加了 Server 端的逻辑:

  1. 在服务端收到对应页面请求时服务端会先返回当前内容然后对页面做失效验证
  2. 如果页面实现,服务端会对失效的页面进行后台增量构建
  3. 当下次请求到达时如果新的页面已经生成成功则会返回新页面的内容,但在此之前还会继续使用旧页面的内容

当然上述的逻辑并不绝对,先增量构建再返回也同样是 ISR,只是一般这样会影响到用户体验一般不推荐。

ISR 适用的场景是:

  1. 网站匹配 SSG 场景
  2. 但对页面有一定的实时性要求

比如说天气预报页面,可能半小时更新一次即可,或者是新闻页面,在存在新数据时再进行增量构建也是一种解决方案。

如何选择

在选择渲染模式时我们通过以下逻辑进行简单的判断:

  1. 客户端页面是否需要动态或交互能力,如果要则 CSR 为必选
  2. 如果页面有 SEO、首屏、性能等需求
    1. 如果页面中想要静态展示的内容对每次访问都可能存在差异——比如每个用户看到的页面信息不同,则可以选择 SSR
    2. 如果页面中静态展示的内容对每次访问没有差异性即可选择 SSG
      1. 如果页面中的静态内容变动较为频繁,则可选择 ISR

其次还要注意 SSRISR 都需要服务端的支持,所以如果只有静态文件服务器那需要的改动就比较大了。

最后

渲染模式其实远不止以上几种,很多场景下都可以进行相应的优化。以下是一些我能想到的场景:

  • 在录入或更新数据时通过 WebHook 等通知构建系统进行增量构建,算是 ISR 的一种变种
  • SSR 场景下可以对静态组件和动态组件进行区分,将静态组件使用 SSG 输出,然后将其拼接到页面中。

所以没有最好的只有最适合的,按需选择最适合自己需求的渲染模式即可。

如果想要看 SSRSSGISR 的具体实现请看我之前的文章。

什么是 CSR、SSR、SSG、ISR - 渲染模式详解的更多相关文章

  1. Extjs MVC开发模式详解

    Extjs MVC开发模式详解   在JS的开发过程中,大规模的JS脚本难以组织和维护,这一直是困扰前端开发人员的头等问题.Extjs为了解决这种问题,在Extjs 4.x版本中引入了MVC开发模式, ...

  2. JavaScript严格模式详解

    转载自阮一峰的博客 Javascript 严格模式详解   作者: 阮一峰 一.概述 除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict m ...

  3. HTTP协议头部与Keep-Alive模式详解

    HTTP协议头部与Keep-Alive模式详解 .什么是Keep-Alive模式? 我们知道HTTP协议采用“请求-应答”模式,当使用普通模式,即非KeepAlive模式时,每个请求/应答客户和服务器 ...

  4. (" use strict")Javascript 严格模式详解

    Javascript 严格模式详解 转载别人的博客内容,浏览了一遍,没有全部吸收,先保存一下链接 http://www.ruanyifeng.com/blog/2013/01/javascript_s ...

  5. Javascript设计模式之装饰者模式详解篇

    一.前言: 装饰者模式(Decorator Pattern):在不改变原类和继承的情况下动态扩展对象功能,通过包装一个对象来实现一个新的具有原对象相同接口的新的对象. 装饰者模式的特点: 1. 在不改 ...

  6. HTTP协议Keep-Alive模式详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp22 HTTP协议Keep-Alive模式详解 1.什么是Keep-Aliv ...

  7. Java开源生鲜电商平台-盈利模式详解(源码可下载)

    Java开源生鲜电商平台-盈利模式详解(源码可下载) 该平台提供一个联合买家与卖家的一个平台.(类似淘宝购物,这里指的是食材的购买.) 平台有以下的盈利模式:(类似的平台有美菜网,食材网等) 1. 订 ...

  8. ext.js的mvc开发模式详解

    ext.js的mvc开发模式详解和环境配置 在JS的开发过程中,大规模的JS脚本难以组织和维护,这一直是困扰前端开发人员的头等问题.Extjs为了解决这种问题,在Extjs 4.x版本中引入了MVC开 ...

  9. Docker Kubernetes Service 网络服务代理模式详解

    Docker Kubernetes  Service 网络服务代理模式详解 Service service是实现kubernetes网络通信的一个服务 主要功能:负载均衡.网络规则分布到具体pod 注 ...

  10. ST MCU_GPIO的八种工作模式详解。

    补充: N.P型的区别,就是一个为正电压启动(NMOS),一个为负电压启动(PMOS) GPIO的八种工作模式详解 浮空输入_IN_FLOATING带上拉输入_IPU带下拉输入_IPD模拟输入_AIN ...

随机推荐

  1. python类详解

    类封装 继承 多态一静态属性1.静态变量和静态方法都属于类的静态成员,它们与普通的成员变量和成员方法不同,静态变量和静态方法只属于定义它们的类,而不属于某一个对象.2.静态变量和静态方法都可以通过类名 ...

  2. 1.springsecurity基于内存和数据库的认证

    1.总结: 昨天主要是使用security实现了基于内存的认证和基于数据库的认证(实际项目中使用): 在security的项目中,必须配置WebSecurityConfigurerAdaptor的实现 ...

  3. 隐私安全常用网站备忘#privacy

    在线查询浏览器WebRTC漏洞 地址 个人数据泄露(#包含扣扣和phone,微博等) 地址 最全的隐私保护指南 地址 钟馗之眼 地址 shodan#暗黑版goole搜索引擎(需代理访问) 地址 社工查 ...

  4. mysql大表修改工具: pt-online-schame-change

    在表数据量很大的时候直接添加字段,以及其他表结构修改,会严重影响线上使用,而且耗费时间很长:使用这个工具可以很好的在线修改表结构. 好处: 降低主从延时的风险 可以限速.限资源,避免操作时MySQL负 ...

  5. MAPPO学习笔记(1):从PPO算法开始

    由于这段时间的学习内容涉及到MAPPO算法,并且我对MAPPO算法这种多智能体算法的信息交互机制不甚了解,于是写了这个系列的笔记,目的是巩固知识,并且进行一些粗浅又滑稽的总结. 1.PPO算法的介绍 ...

  6. #Powerbi 季度时间进度计算

    上一篇我们学习了月度时间进度的计算方法,今天我们学习季度时间进度的测算. 思路:找出目前共计消耗了多少天(季度),目前日期所在的季度共有多少天,两者相除即是季度的时间进度 首先列出DAX函数:   本 ...

  7. 🚀 jdbc-plus是一款基于JdbcTemplate增强工具包, 已实现分页、多租户、动态表名等插件,可与mybatis、mybatis-plus等混合使用

    jdbc-plus简介 jdbc-plus是一款基于JdbcTemplate增强工具包, 基于JdbcTemplate已实现分页.多租户.动态表名等插件,可自定义扩展插件,可与mybatis.myba ...

  8. 2021-01-22:java中,HashMap的写流程是什么?

    福哥答案2021-01-22:jdk1.7写流程:1.如果table数组为空,table数组初始化,调用inflateTable方法.2.如果key为null,调用putForNullKey()方法, ...

  9. 2021-02-25:给定一个正数数组arr,请把arr中所有的数分成两个集合。如果arr长度为偶数,两个集合包含数的个数要一样多;如果arr长度为奇数,两个集合包含数的个数必须只差一个。请尽量让两个集合的累加和接近,返回最接近的情况下,较小集合的累加和。

    2021-02-25:给定一个正数数组arr,请把arr中所有的数分成两个集合.如果arr长度为偶数,两个集合包含数的个数要一样多:如果arr长度为奇数,两个集合包含数的个数必须只差一个.请尽量让两个 ...

  10. 2021-10-24:快乐数。编写一个算法来判断一个数 n 是不是快乐数。「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1,也可能是

    2021-10-24:快乐数.编写一个算法来判断一个数 n 是不是快乐数.「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和.然后重复这个过程直到这个数变为 1,也可能是 ...