共计 3660 个字符,预计需要花费 10 分钟才能阅读完成。
背景
周末在网上冲浪,看到个音讯:NextJS 9.3 将动态站点生成性能引入了 NextJS 平台。
动态站点生成
, 也就是所谓的 SSG : Static Site Generation
。
喝了口水,顺便回顾了下当初的几种渲染模式:
SSR
(Server Side Rendering)SSG
(Static Site Generation)SSR With hydration
CSR with Pre-rendering
CSR
(Client Side Rendering)Trisomorphic Rendering
都不是什么陈腐玩意,就总结温习一下,顺便分享给大家,心愿能给各位带来一些启发。
注释
1. SSR (Server Side Rendering)
SSR,服务端渲染。
服务器出现响应于导航为服务器上的页面生成残缺的 HTML。这样能够防止在客户端进行数据获取和模板化的其余往返过程,因为它是在浏览器取得响应之前进行解决的。
服务器渲染通常会产生疾速的 First Paint(FP)和 First Contentful Paint(FCP)。
在服务器上运行页面逻辑和出现能够防止向客户端发送大量 JavaScript,这有助于实现疾速的交互工夫(TTI)。
这是有情理的,因为应用服务器渲染,实际上只是将文本和链接发送到用户的浏览器。
这种办法能够在很大范畴的设施和网络条件下很好地工作,并且能够带来乏味的浏览器优化,例如流文档解析。
流程:
浏览器 –> 服务器 –> 服务器执行渲染 –> index.html(实时渲染的内容)) –> Render –> bundle.js + images –> Render
长处
- 内容立刻可用 - 因为将 HTML 发送给客户端,所以简直会立刻看到页面内容。
- 无需获取其余客户端 - 现实状况下,服务器出现过程将进行所有必须的调用以获取数据,因而不会从客户端进行任何其余服务调用。
- 非常适合 SEO
毛病
- 服务器上的速度较慢 - 须要渲染两次页面:一次在服务器上,一次在客户端上。共事也可能正在从服务器进行服务调用以出现页面,所有这些都须要工夫,因而可能会提早 HTML 向客户端的初始发送。
- 与某些 UI 库不兼容 - 如果你用的某些库应用了 window,那你就要想方法来解决了。因为 Node 中没有
window
或者document
。
2. SSG (Static Site Generation)
SSG:动态网站生成。
动态网站生成相似于服务器端渲染,不同之处在于您在 构建时 而不是在 申请时 渲染页面。
与服务器渲染不同,因为不用动静生成页面的 HTML,因而它还能够实现始终如一的疾速到第一字节的工夫。
通常,动态出现意味着提前为每个 URL 生成独自的 HTML 文件。
借助事后生成的 HTML 响应,能够将动态渲染器部署到多个 CDN,以利用边缘缓存的劣势。
长处
- 内容立刻可用 - 因为将 HTML 发送给客户端,所以简直会立刻看到页面内容。
- 无需获取其余客户端 - 现实状况下,服务器出现过程将进行所有必须的调用以获取数据,因而不会从客户端进行任何其余服务调用。
- 非常适合 SEO
- 快- 动态内容的出现速度速度十分快。
- 没有服务器 - 不用运行服务器。
毛病
- 大型站点可能会很慢 - 如果路由很多,速度可能会变慢。
- 与某些 UI 库不兼容 - 如果你用的某些库应用了 window,那你就要想方法来解决了。因为 Node 中没有
window
或者document
。
3. SSR With hydration
hydration, 直译为 水合
。
让人一脸懵逼。
简略点讲,将性能放回到曾经在服务器端中出现的 HTML 中的整个过程,称为水合。
换句话说就是,对已经渲染过的 HTML 进行从新渲染的过程称为水合。
此办法试图通过同时进行客户端渲染和服务器渲染,达到一种均衡。
导航申请(例如整页加载或从新加载)由服务器解决,该服务器将应用程序出现为 HTML,而后将 JavaScript 和用于出现的数据嵌入到生成的文档中。
现实状态下,就能够像服务器渲染一样实现疾速的 First Contentful Paint,而后通过应用称为(re)hydration 的技术在客户端上再次渲染来 修补
。
这是一个新鲜的解决方案,然而它也可能具备一些相当大的性能缺点。
带水合的 SSR 的次要毛病是:
即便改良了 First Paint
,它也可能对 可交互工夫
产生重大负面影响。
SSR 的页面通常看起来具备欺骗性,并且具备交互性,然而在执行客户端 JS 并附加事件处理程序之前,实际上无奈响应输出
。
在挪动设施上可能要花费几秒钟甚至几分钟。
原理示意:
与 JS 导致的提早互动相比,这个模型造成的问题可能会更加重大:
服务器响应导航申请返回了应用程序 UI 的数据形容。同时,但它还返回了用于组成该 UI 的源数据以及该 UI 的实现的残缺脚本,该脚本随后在客户端启动。
仅在 bundle.js 实现加载和执行后,该 UI 才会变为可交互。
举个例子:
蓝色局部蕴含了初始的 3 个 checkbox, 以及须要加载的 bundle.js,
一开始,你会立刻看到 UI,等 bundle 加载并执行实现之后,页面才会更新,进入可交互状态。
从实在网站中收集的成果指标表明,应用 SSR 水合模式成果并不好,强烈建议不要应用它。
起因归结为用户体验:最终很容易使用户陷入 怪异的山谷
。
4. CSR with Pre-rendering
Pre-render
原理是:在构建阶段就将 html 页面渲染结束,不会进行二次渲染。
也就是说,当初打包时页面是怎么样,那么预渲染就是什么样。
等到 JS 下载并实现执行,如果页面上有数据更新,那么页面会再次渲染。这时会造成一种数据提早的错觉。
Pre-render
利用 Chrome
官网出品的 Puppeteer
工具,对页面进行爬取。
它提供了一系列的 API, 能够在无 UI 的状况下调用 Chrome
的性能, 实用于爬虫、自动化解决等各种场景。
它很弱小,所以很简略就能将运行时的 HTML 打包到文件中。
原理是:在 Webpack
构建阶段的最初,在本地启动一个 Puppeteer
的服务,拜访配置了预渲染的路由,而后将 Puppeteer
中渲染的页面输入到 HTML
文件中,并建设路由对应的目录。
以此,达到预渲染的目标。
流程:浏览器 –> 服务器 –> index.html(预渲染的内容) –> Render –> bundle.js + images –> Render
5. CSR (Client Side Rendering)
CSR, 顾名思义,客户端渲染。
客户端渲染,意味着: 间接应用 JavaScript 在浏览器中渲染页面
。
所有逻辑,数据获取,模板和路由均 在客户端而不是服务器上解决
。
CSR 示意图:
流程:浏览器 –> 服务器 –> index.html(白屏) –> bundle.js –> images –> Render
长处
- 在服务器上疾速 - 因为仅出现空白页,所以出现速度十分快。
- 反对动态 - 空白页能够通过 S3 之类的服务动态生成和提供,从而使速度更快。
- 反对单页应用程序 - 客户端渲染是惟一反对单页应用程序或 SPA 的模型。
- 老本绝对较低 – CSR 绝对于 SSR/SSG,更容易开发 / 保护。
毛病
- 没有初始渲染 - 如果利用很大,或者客户的连贯速度很慢,加载工夫过长,用户体验就不太好。
6. 三态渲染
如果你能够联合 Service-Worker
, 则 三态渲染
模式也可能派上用场。
在三态渲染模型中,能够应用服务器流式渲染进行初始导航,而后让 service worker 在 html 加载实现后,持续进行导航 html 的渲染。
这样能够使缓存的组件和模板放弃最新状态,并启用 SPA 款式的导航,以在同一会话中出现新视图。
如果能够在服务器,客户端页面和 service worker 之间 共享
雷同的模板和路由代码时,这种办法非常无效。
三态渲染模型:
7. 服务端渲染 VS 客户端渲染
服务器渲染会为每个 URL 按需生成 HTML,比仅提供动态渲染内容要慢。
同时,也有一些优化空间:服务器渲染 + HTML 缓存能够大大减少服务器渲染工夫。
服务器渲染的劣势在于:与动态渲染相比,它可能提取更多 "实时" 数据并响应更残缺的申请集。
总结
从 SSR -> CSR,以及两头不同的渲染模式,都在图里:
本文中介绍的 6 种渲染模式,至于如何抉择,这里也给出一些不成熟的倡议:
- 对 seo 要求不高,同时
对操作需要比拟多
的我的项目,比方一些治理后盾零碎,倡议应用 CSR。因为只有在执行完 bundle 之后,页面能力交互,单纯能看到元素,却不能交互,意义不大,而且 SSR 会带来额定的开发和保护老本。 - 如果页面
无数据
,或者是纯动态
页面,倡议应用 pre-render。因为这是一种通过预览打包的形式构建页面,也不会减少服务器累赘。 - 对 seo 和加载速度有比拟大需要的,同时页面数据申请多的状况,倡议应用
SSR
。
结尾
好了,天都黑了,大略就是这么多。
满腹经纶,如有谬误,欢送留言斧正。
周末在钻研 Reciol.js, 感觉挺有意思,前面大略会出一篇剖析的文章,敬请期待哦。
参考资料
- https://umijs.org/zh-CN/docs/…
- https://juejin.im/post/684490…
- https://juejin.im/post/684490…