写在后面
上篇 SSR 的利与弊列举了 SSR 渲染模式的 6 大难题:
- 难题 1:如何利用存量 CSR 代码实现同构
- 难题 2:服务的稳定性和性能要求
- 难题 3:配套设施的建设
- 难题 4:钱的问题
- 难题 5:hydration 的性能损耗
- 难题 6:数据申请
这些问题是 SSR 始终以来远不如 CSR 利用宽泛的次要起因,但时至今日,Serverless、low-code、4G/5G 网络环境三大时机让 SSR 呈现了新的转折,落地开花正过后
第一大时机:Serverless
无服务器计算(serverless computing)将服务器相干的配置管理工作通通交给云供应商去做,以加重用户治理云资源的累赘
对云计算用户而言,Serverless 服务可能(主动)弹性伸缩而无需显式预配资源,不仅免去了云资源的管理负担,还可能按应用状况计费,这一特点在很大水平上解决了“难题 4:钱的问题”:
引入 SSR 渲染服务,实际上是在网络结构上加了一层节点,而大流量所过之处,每一层都是钱
将组件渲染逻辑从客户端改到服务器执行,势必会减少老本,但无望通过 Serverless 将个中老本降到最低
另一方面,Serverless Computing 的要害是 FaaS(Function as a Service),由云函数提供惯例计算能力:
间接运行后端代码,而无需思考服务器等计算资源以及服务的扩展性、稳定性等问题,甚至连日志、监控、报警等配套设施也都开箱即用
也就是说,喂给 FaaS 一个 JavaScript 函数,就能上线一个高可用的服务,无需操心如何承载大流量(几万 QPS)、如何保障服务稳固牢靠……听起来有些跨时代是么,实际上,AWS Lambda、阿里云 FC、腾讯云 SCF 都曾经是成熟的商业产品了,甚至可能收费试用
无状态的模板渲染工作尤其适宜用云函数(输出 React/Vue 组件,输入 HTML)来实现,“难题 2:服务的稳定性和性能要求”最要害的后端专业性问题迎刃而解,SSR 面临的技术难题从一个高可用的组件渲染服务放大到了一个 JavaScript 函数中:
与客户端程序相比,服务端程序对稳定性和性能的要求严苛得多,例如:
- 稳定性:异样解体、死循环(由前端人员自行解决)
- 性能:
内存 /CPU 资源占用(由 FaaS 基础设施解决)、响应速度(网络传输间隔等都要思考在内)
如何应答大流量 / 高并发,如何辨认故障,如何降级 / 疾速复原(由 FaaS 基础设施解决),哪些环节须要加缓存,缓存如何更新……
FaaS 基础设施解决了大部分的性能问题和可用性问题,函数内的稳定性问题可通过纯前端伎俩解决,至于剩下的响应速度、缓存 / 缓存更新问题,则须要引入另一个云计算概念——边缘计算
边缘计算
所谓的边缘计算,就是将计算和数据存储散布到离用户更近的(CDN)节点(或者叫边缘服务器,Edge server)上,节俭带宽的同时更快响应用户申请:
Edge computing is a distributed computing paradigm that brings computation and data storage closer to the location where it is needed, to improve response times and save bandwidth.
(摘自 Edge computing)
像传统 CDN 通过缩短动态内容与最终用户之间的物理间隔来减速资源拜访,同时缩小了应用服务器的负载一样,反对边缘计算的 CDN 容许将云函数部署到边缘节点中 ,减速服务响应,同时依靠 CDN 轻松管制缓存策略,甚至可能实现 动静拆散的边缘流式渲染(ESR):
P.S. 基于边缘计算的 SSR 的更多信息,见前端性能优化:当页面渲染遇上边缘计算
第二大时机:low-code
如果说 FaaS 解决了 SSR 落地最外围的服务可用性问题,给 SSR 插上了双翼,那么low-code 则是让 SSR 得以冲向天际的助飞跑道
因为low-code 简直解决了其余的所有难题:
- 难题 1:如何利用存量 CSR 代码实现同构
难题 2:服务的稳定性和性能要求- 难题 3:配套设施的建设
难题 4:钱的问题- 难题 5:hydration 的性能损耗
- 难题 6:数据申请
源码开发模式下难以解决的问题,在 low-code 模式下有了不同维度的解法,就像是通过几何办法来解决代数问题
难题 1:如何利用存量 CSR 代码实现同构
要让现有的 CSR 代码在服务端跑起来,先要解决诸多问题,例如:
- 客户端依赖:分为 API 依赖和数据依赖两种,比方
window/document
之类的 JS API、设施相干数据信息(屏幕宽高、字体大小等)- 生命周期差别:例如 React 中,
componentDidMount
在服务端不执行- 异步操作不执行:服务端组件渲染过程是同步的,
setTimeout
、Promise
之类的都等不了- 依赖库的适配:React、Redux、Dva 等等,甚至还有 第三方库等不确定是否跑在 universal 环境,是否须要跨环境共享状态,以状态管理层为例,SSR 要求其 store 必须是可序列化的
- 两边共享状态:每一份须要共享的状态都要思考(服务端)如何传递、(客户端)如何接管
首先,low-code 模式不同于源码开发,现有的 CSR 代码无奈间接迁徙到 low-code 平台上来,其次,low-code 配置化的开发模式提供了人造的细粒度逻辑拆分和残缺的精密控制力,体现在:
- 细粒度逻辑拆分:各个生命周期函数独立配置
- 残缺的精密控制力:依赖库、生命周期、异步操作、共享状态严格受控,low-code 平台全权管制所填代码的编译时、运行时环境
客户端依赖虽无奈打消,但可能像函数式编程中的副作用一样管控起来,比方将其束缚到特定的生命周期函数(componentDidMount
)中,使之仅在客户端执行,防止影响服务端。生命周期的差别可通过 low-code 平台让用户产生强感知,比方在编辑、预览等环节强化差别。对于不反对的异步操作,可在编辑阶段进行校验并提醒。至于依赖库和状态共享形式,low-code 平台可能全权管制,将其束缚到反对范畴内
总之,low-code 轻松解决了源码开发模式下辣手的如何束缚写法、如何管控不确定性的问题
难题 3:配套设施的建设
SSR 最外围的局部是渲染服务,但除此之外还要思考:
- 本地开发套件(校验 + 构建 + 预览 /HMR + 调试)
- 公布流程(版本治理)
一整套的工程设施,在 SSR 模式下都须要重新考虑
这些配套设施是 SSR 要解决的问题,low-code 也面临同样的问题,因而,SSR 可能在肯定水平上复用 low-code 提供的在线研发链路反对,只对其局部环节进行扩大,升高配套设施建设的老本
难题 5:hydration 的性能损耗
组件作为一层形象,在提供模块化开发、组件复用等工程价值的同时,也带来了一些问题。典型的,交互逻辑与组件渲染机制绑定在了一起,这是 SSR 须要 hydration 的根本原因:
客户端接到 SSR 响应之后,为了反对(基于 JavaScript 的)交互性能,依然须要创立出组件树,与 SSR 渲染的 HTML 关联起来,并绑定相干的 DOM 事件,让页面变得可交互,这个过程称为 hydration
也就是说,只有依然依赖组件这层形象,hydration 的性能损耗就无可避免。在源码开发模式下,组件无可替代,因为没有与之等价的形象形容模式。然而,在 low-code 模式下,其输入产物(配置数据)也是一种形象形容模式,如果可能具备与组件等同的表达力,就齐全有可能去掉组件这层形象,不用再背负 hydration 的性能损耗
另一方面,对于无交互(纯动态展现)、弱交互(动态展现带埋点 / 跳转)的偏动态场景,low-code 平台也能精确地辨认进去,防止不必要的 hydration
难题 6:数据申请
服务端同步渲染要求先发申请,拿到数据后才开始渲染组件,那么面临 3 个问题:
- 数据依赖要从业务组件中剥离进去
- 缺失客户端公参(包含 cookie 等客户端会默认带上的 header 信息)
- 两边数据协定不同:服务端可能有更高效的通信形式,比方 RPC
low-code 开发模式下,数据依赖以配置化的模式录入,人造剥离,客户端公参、数据协定等均可通过 low-code 平台来配置,比方配 HTTP、RPC 两套协定,按环境主动选用
第三大时机:4G/5G 网络环境
挪动时代晚期,离线 H5 是业界最佳实际,因为在线页面意味着秒级的加载工夫,离线页面有着微小的加载速度劣势
但随着网络环境的倒退,离线页面的加载速度劣势曾经不再是决定性因素(小程序的大暴发足以阐明问题),在线页面的动态化个性备受关注,(SSR 无能为力的)离线场景越来越少,SSR 的用武之地越来越多
参考资料
- 伯克利研究员们眼中的 Serverless Computing
- FaaS 给前端带来了什么?
有所得、有所惑,真好
关注「前端向后」微信公众号,你将播种一系列「用 心原创」的高质量技术文章,主题包含但不限于前端、Node.js 以及服务端技术
本文首发于 ayqy.net,原文链接:http://www.ayqy.net/blog/2020…