目录
一、客户端渲染——CSR(Client Side Rendering)
二、服务器端渲染——SSR(Server Side Rendering)
三、静态站点生成——SSG(Static Site Generation)
四、增量静态生成——ISR(Incremental Static Regeneration)
五、分布式的持续渲染——DPR(Distributed Persistent Rendering)
六、对比及选择
七、相关参考
本文汇总了前端涉及到的几种不同渲染方式
对于典型的 CSR 应用程序,浏览器仅接收一个用作应用程序容器的 HTML 页面,因此也称为单页应用。浏览器会优先请求到index.html文件,文件中并没有过多的DOM元素,直接打开的话会展示为空白页。之后会通过拉取JS、CSS文件,执行解析,对于像Vue,React,Angular等框架,会通过JS在定义的根节点上挂在DOM节点,最终将整体页面呈现给用户。
早期使用 JSP 或其他模板渲染引擎(如ejs,jade等)来构建应用就属于SSR的范畴,浏览器发起请求后,服务端会在内部完成数据请求和html的拼装操作,浏览器接收到的便是可直接渲染的html文件,而无需等待后续JS和css文件的加载。
起初的SSR在内容更新/跳转,都需要请求服务器,服务器会根据请求地址,返回新的页面内容。
在 React, Vue 等框架的加持下,SSR 一般指的是首屏服务端渲染或同构渲染(Isomorphic render)
,即新开页面访问 SSR 应用时,首屏会返回完整的 html,浏览器通过注水(hydrate
)成为 React 或 Vue 应用,后续用户进行跳转等操作时不会再向服务端请求 html,而是以类似单页应用的方式进行。
同构渲染
同构渲染是 15 年左右 React 火了一段时间后提出的概念,原文是 Isomorphic rendering,但是很快就有人驳斥不应该用 Isomorphic 这个词,而应该用 Universal Rendering。
它可以分为两个部分:
这两种渲染方式的不同点在于运行环境的不同。单核心点是同一份代码可以在客户端和服务器端运行,两个环境的渲染结果保持一致。因此需要实现客户端和服务器端的路由、页面模板和数据共享。
它包含了两个重要的概念:
脱水(dehydrate)
将组件树序列化成静态的 HTML 片段,能直接看到初始视图,不过已经无法与之交互了,但这种便携的形态尤其适合网络传输。这个脱去动态数据,成为风干标本一样的静态快照的过程被称为脱水(dehydrate)。
注水(hydrate)
与脱水相反,将这个 html 躯干复活为 Vue 应用的过程称为注水。客户端并不重新生成 HTML 组件,而是重用服务器发送给它的 HTML,并附加「数据」与「交互性」,构建成完整的 Vue 应用,这个过程被称为注水(hydrate)。
通过同构渲染的方式结合了SSR和CSR的优势,即保证了首屏渲染速度及SEO友好性,又将后续路由处理特定的实现(如vue-router,react-router),减少了渲染服务器的负载。
SSG 与 SSR 的原理类似,但不同之处在于 HTML 文件是预先生成的,一般是在构建阶段完成html的拼装,将其转换为静态内容的模式,而不是在服务器实时生成。
ISR最早由 Next.js 在 9.5 版本中提出,它结合了 SSG 和 SSR 的优势。
核心思想是将内容区分为主要内容和次要内容。主要内容的静态页面采用SSG的方式在构建时生成。而对于次要内容则借鉴SSR得方式保持动态,在用户首次访问时进行渲染。一旦渲染完成,生成的静态页面被缓存,并在后续的请求中被直接提供,以提高性能和响应速度。
后续更新遵循 stale-while-revalidate 的逻辑,即始终返回 CDN 的缓存数据(无论是否过期);如果数据已经过期,那么触发异步的预渲染,异步更新 CDN 的缓存。
DPR是由Netlify提出个一个提案,详见Distributed Persistent Rendering: a new idea in the Jamstack to make deploys faster and bring a wider range of use cases.
DPR 本质上讲,是对 ISR 的模型做了几处改动,并且搭配上 CDN 的能力:
1、去除了 fallback 行为,而是直接用 On-demand Builder(按需构建器)来响应未经过预渲染的页面,然后将结果缓存至 CDN;
2、数据页面过期时,不再响应过期的缓存页面,而是 CDN 回源到 Builder 上,渲染出最新的数据;
3、每次发布新版本时,自动清除 CDN 的缓存数据。
方式 | 优点 | 缺点 |
CSR | 1、分工明确:前后端彻底分离 2、性能高:页面切换即时性,网站的可移植性,可访问性更高 3、服务器负载小:切换页面不需要重新加载,路由跳转是基于特定的实现(如 vue-router,react-router 等前端路由),而非原生浏览器的文档跳转,避免了不必要的整个页面重载,服务器负载更小。甚至可以整站可以直接上CDN,前端可以不需要单独的服务器 |
1、SEO不友好(现在部分搜索引擎支持了对CSR页面的动态捕获)。 2、首屏渲染慢,因为是需要JS来控制页面的渲染,所以渲染部分被放到了js的后面,因此会出现相对较长的白屏。 |
SSR | 1、SEO比较友好,搜索引擎爬虫可以直接抓取页面的有效内容 2、首屏渲染快,服务端渲染直接返回带有数据的 HTML 文本,浏览器只需解析 HTML 并构建 DOM 树,无需额外执行 JS 来渲染首屏元素 |
1、项目复杂度变的更高,需要服务器的计算资源和公网流量部署服务,并且消耗的资源与页面的访问量成正相关,当页面的访问量突增时,渲染服务也需要进行扩容; 2、服务端只能部署在有限的几个地域,对于距离服务端较远的用2户而言,加载速度跟静态资源的 CDN 相比,慢了一个数量级(通常是 1-5ms VS 50-100+ms); 3、日常也存在传统服务端同样的运维、监控告警等方面的负担,团队需要额外的人力来开发和维护。 |
SSG | 1、性能高:相比 SSR 减轻了服务器压力,需要额外做一套node服务,还可以将生成的静态资源放到 CDN 上,用户始终通过 CDN 加载页面核心内容,可以高效利用 CDN 边缘节点的缓存,速度快 2、SEO 友好:章内容静态化,搜索引擎爬虫可以直接抓取到最终页面内容 3、易于部署:生成的静态页面可以直接部署到任何支持静态文件的 Web 服务器上,无需依赖 Node 环境等。 4、高度安全性:由于服务器不需要运行程序,因此服务器漏洞仅限于操作系统本身,维护也更加方便。 |
1、大型网站,静态文章千万级、亿级页面,靠每次生成耗时太久 2、需要有对应的缓存刷新策略,以保证更新的及时性 |
ISR | 1、在静态和动态之间找到了一个平衡点。对于不经常变动的内容,可以通过SSG生成完全静态的页面,从而实现快速加载和低服务器负载 | 1、访问到没被预渲染过的次要内容触发 fallback,需要进行 CSR,加载较慢。 2、访问到之前被预渲染过,但已经过期且未更新的页面,会得到过期的缓存响应。用户刷新一次,才能看到新的数据。 |
DPR | 1、是ISR的升级版,去除了 fallback 行为,而是直接用 On-demand Builder | 1、普及度较低 |
决策点 | 是 | 否 |
是否强制要求首屏性能 | SSR,SSG,ISR,DPR | 纯 CSR 不可取 |
否关注 SEO | SSR,SSG,ISR,DPR | 纯 CSR 不可取 |
是否具有丰富可交互性、需要用户能力、差异化渲染 | CSR | SSR,SSG,ISR,DPR |
页面结构 & 路由是否复杂、数据更新是否频繁、是否依赖实时数据接口 | 首先排除 SSG、如果内容不能拆解,ISR、DPR 也不便接入 | 无限制 |
是否有低码或微前端等框架的使用 | 排除SSG、ISR、DPR选项 | 无限制 |
是否接受引入服务器运维成本 | 无限制 | SSR不可选 |
旧有实现中是否有浏览器依赖如 UI 框架内对 DOM、BOM,或 Hybrid 场景下的 JSBridge 的使用 | SSR、SSG 受限 | 无限制 |
新一代Web建站技术栈的演进:SSR、SSG、ISR、DPR都在做什么? - 知乎
Visual Explanation and Comparison of CSR, SSR, SSG and ISR
Rendering on the Web
带你深入理解 CSR,SSR,SSG 等常用渲染模式 - 专栏 - 声网 RTE 开发者社区
一文看懂Next.js渲染方法:CSR、SSR、SSG和ISR-51CTO.COM
什么是 CSR、SSR、SSG、ISR - 渲染模式详解_csr和ssr_嘿嘿不务正业的博客-CSDN博客