SSR 实践指南
目录 🔗︎
SSR 概念与分类 🔗︎
SSR(服务端渲染) 🔗︎
服务端生成 HTML,适用于 SEO 优化和首屏加载速度提升。
SSG(静态化 SSR) 🔗︎
结合了 CDN 缓存 HTML 的方式,提前生成静态页面并缓存到 CDN 中,进一步提升性能。
个性化 SSR 🔗︎
根据设备性能动态调整渲染策略:
- 高端机:CSR(客户端渲染)
- 低端机:SSG(静态化 SSR)
Hydrate(水合) 🔗︎
定义: 执行业务 Bundle,进行事件和状态的绑定。
特点:
- 如果水合结果与 SSR 渲染结果一致,则不会重绘。否则可能导致LCP重新计算,导致LCP变大。
- 如果两者不一致,会重新渲染,可能导致页面错乱或者闪烁。(js和水合的html结构必须一样,比如在代码中根据isSSR判断渲染不同的jsx可能导致页面样式错乱)
Serverless 🔗︎
通过 Faas(函数即服务)的方式部署 Serverless 服务,提供页面渲染能力。
1. FaaS 的定义 🔗︎
- FaaS(函数即服务) 是一种无状态、事件驱动的计算服务。
- 函数独立部署,自动扩容,按需运行。
- Faas一般只有内部rpc接口比如hsf,无法对外提供http,所以一般上层都需要网关转发
2. Serverless 的定义 🔗︎
- Serverless 是一种无需管理服务器的架构模式。
- 包括计算(如 FaaS)、存储、数据库等基础设施。
3. FaaS 与 Serverless 的关系 🔗︎
- FaaS 是 Serverless 的一部分:
- FaaS 提供计算能力。
- Serverless 是更广的概念,涵盖整个应用的无服务器化。
4. FaaS 的特点 🔗︎
- 无状态:函数不保存状态,需外部存储管理。
- 自动扩容:根据流量动态调整资源。
- 事件驱动:由 HTTP 请求、定时任务等触发。
- 独立部署:支持细粒度拆分和微服务架构。
5. Serverless 的特点 🔗︎
- 全栈支持:包括计算、存储、网络等。
- 按需计费:只为实际使用付费。
- 高可用性:云服务商保障底层设施稳定。
- 简化运维:无需管理服务器或运行时环境。
6. 通过 FaaS 部署 Serverless 服务 🔗︎
- 使用 FaaS 提供页面渲染能力。
- 将渲染逻辑封装为函数,通过 HTTP 请求触发。
- 优势:
- 并行处理请求,提升性能。
- 差异化对待请求,实现降级策略。
7. FaaS 的优势 🔗︎
- 高性能:并行处理,动态扩容。
- 灵活性:根据请求内容调整逻辑。
- 低成本:无需管理服务器。
- 快速迭代:独立部署,支持快速上线。
同构 🔗︎
代码同时支持 CSR 和 SSR,实现前后端统一。
专业知识与案例 🔗︎
知识点 | 案例 |
---|---|
SSR 渲染时,如果前端无数据,兜底发起二次请求 | SSR |
一次请求中多次调用同一个 HSF,入参相同时可以复用返回结果 | SSR |
日志一般在 home/admin/logs 下:- cai 是 Nginx 日志- [appname] 下是应用日志- bin 下是一些有用的脚本 | SSR |
压测 + 日志分析发现内存泄漏 | SSR |
统一封装 SDK(如 Midway-FaaS 的组件,用于日志处理等)给 Faas 函数使用 | SSR |
工具 | 用途 |
---|---|
npm 包:escapeHtml | 在 SSR 中用来转义 HTML 字符串 |
调试方法 🔗︎
如何切到 SSR:
- 在浏览器开发者工具中,通过 Network 面板 Block 掉 JS 请求。
- 查看 SSR 的渲染结果(即水合之前的结果)。
流式渲染 🔗︎
定义: 流式渲染是一种优化技术,主要用于解决多个请求中某个请求先返回时,将数据优先发送给客户端的问题。
特点:
- 对 QPS(每秒查询率)有一定损耗。
- 提升用户体验,减少等待时间。
源站架构 🔗︎
- 通用网关:处理代理转发,分站点代理转发
- 渲染网关侧有非业务容灾,比如页面请求失败兜底/404
- 数据网关
- 一般faas层有业务限流接口容灾(单机限流)包括应用层的容灾,比如多语言容灾fallbackCache
vm模版编译 🔗︎
vm模版是通过React语法实现,单独的vm执行编译一下,提前开发阶段发现问题,避免代码穿透。
ReactServer.renderToStaticMarkup(
<DocumentContext.Provider value={context}>
<DocumentElement />
</DocumentContext.Provider>
);
页面路由 🔗︎
比如aa.com/a/p/1.html -> aa.pc.a-p 作为配置的唯一key。 通过path-to-regexp
这个包实现pathName和url匹配