本文已参与「新人创作礼」活动,一起开启掘金创作之路
CSR
普通的单页应用只有一个 HTML,初次请求返回的 HTML 中没有任何页面内容 ,需要通过网络请求 JS bundle 并渲染,整个渲染过程都在客户端完成, 所以叫客户端渲染(CSR)。这种渲染方式虽然在后续的页面切换速度很快,但是也明显存在两个问题:
白屏时间过长:在 JS bundle 返回之前,页面一直是空白的。
假如 bundle 体积过大或者网络条件不好的情况下,体验会更不好
SEO 不友好:搜索引擎访问页面时,只会看 HTML 中的内容,
默认是不会执行 JS,所以抓取不到页面的具体内容
SSR
相信大家对 SSR 不会陌生,它是在服务端直接实时同构渲染当前用户访问的页面, 返回的 HTML 包含页面具体内容,提高用户的体验。 React 从框架层面直接提供支持, 只需要调用 renderToString(Component) 函数即可得到 HTML 内容。
SSR 方案虽然解决了 CSR 带来的两个问题
需要一个服务器承载页面的实时请求、渲染和响应, 这无疑会增大服务端开发和运维的成本。
另外对于一些较为静态场景,比如博客、官网等,它们的内容相对来说比较确定, 变化不频繁,每次通过服务端渲染出来的内容都是一样的, 无疑浪费了很多没必要的服务器资源。 这时,有没有一种方案可以让这些页面变得静态呢? 这时,静态站点生成(SSG,也叫构建时预渲染)诞生了。
SSG
应用编译构建时预先渲染页面,并生成静态的 HTML。
把生成的 HTML 静态资源部署到服务器后,
浏览器不仅首次能请求到带页面内容的 HTML ,
而且不需要服务器实时渲染和响应,
大大节约了服务器运维成本和资源。
SSG 虽然很好解决了白屏时间过长和 SEO 不友好的问题,
但是它仅仅适合于页面内容较为静态的场景,
ISR
要增量静态再生成(Incremental Static Regeneration)方案了
SSR + CSR
二者的有机结合,大大减少后端服务器的压力和成本的同时,也能提高页面切换的速度
SSG + CSR
静态内容走 SSG:对于页面中较为静态的内容,比如导航栏、布局等,可以在编译构建时预先渲染静态 HTML
动态内容走 CSR:一般会在 useEffect 中请求接口获取动态数据,然后进行页面重新渲染
SSG+SSR
静态内容走 SSG: 编译构建时把相对静态的页面预先渲染生成 HTML,浏览器请求时直接返回静态 HTML
动态内容走 SSR: 浏览器请求未预先渲染的页面,在运行时通过 SSR 渲染生成页面, 然后返回到浏览器,并缓存静态 HTML,下次命中缓存时直接返回
ISR
ISR 相比于 SSG + CSR 来说,动态内容可以直接直出,
进一步提升了首次访问页面时的体验;
相比于 SSR + CSR 来说,
减少没必要的静态页面渲染,节省了一部分后端服务器成本。
1
需要在渲染之前获取所有数据 由于需要渲染一个完整的跟组件, 所以必须等所有的数据加载完毕,才可以开始渲染
所以可拆包技术 大的bundjs拆开 单独下载并执行
总结
等待上一步执行完,才能进行下一步
服务端获取所有的数据----》服务端渲染---〉 客户端家在代码进行注水----》页面可交互
分别执行2次ReactDOM.renderToString方法 通过拆分React DOM Root的方式 完成服务端渲染的拆分 从而规避了数据获取时拖延服务端渲染的问题
直到所有组件完成注水,才可以被交互
吸水时执行js逻辑以及绑定事件的回调的过程 react要求前端生产的组件树和服务端产出的组件树保持一至, 会造成前端渲染内容覆盖服务端渲染内容
React18 SSR
suspense 支持服务端渲染 支持服务端流失传输HTML 支持客户端选择性吸水
suspense
可以做到服务端暂停SSR工作,并在确定渲染内容后,继续返回
将渲染进行拆分,再结合选择性注水的能力, 加快页面可交互时间
解决了上面3个问题
1.需要在渲染前获取所有数据
可以优先返回静态内容,并在获取数据后继续返回余下内容
2.需要全部内容加载后才能注水
可以将代码拆分与服务端渲染结合使用 HRML在完成局部渲染后,可以优先对局部注水
3.直到所有组件注水完成后才可以交互
优先选择用户正在交互的组件注水