SPA 和 React:你并不总是需要服务器端渲染
本文最初发表于 The New Stack 网站,由 InfoQ 中文站翻译分享。
你可能已经注意到,React 文档的“Start a New React Project”部分不再推荐使用 CRA(Create React App)。Create React App 曾经是构建 React 应用程序的首选方式(它只需要客户端路由和页面渲染)。但现在,React 文档建议从支持服务端渲染(server-side rendering,SSR)的流行 React 框架中选择一个。
我曾经使用“生产级 React 框架”列表中的所有框架构建过应用,但是我也花了很多年的时间构建只需要客户端功能的 SPA(单页应用),而且一切运行良好。
虽然有很多应用确实需要服务器端渲染,但是也有不少的应用并不需要服务器端渲染。如果选择 SSR React 框架,可能会引发新的问题而不是解决问题。
正如这个缩写所示,SPA 只有一个页面。SPA 可能有导航,但是当你从一个“页面”点击到另一个“页面”时,你所经历的是路由,而不是页面。当导航至一个新路由时,React 会接管并用 HTML 和通常通过客户端 HTTP 请求获取到的数据为“页面”填充内容。
SSR 应用与之不同。服务器端渲染的应用实际上是有页面的。数据来自服务器,页面在服务器上进行编译,然后将最终输出作为完整的 HTML 网页发送到浏览器。
如前所述,使用 SSR 需要服务器,通常涉及到云供应商。如果你的 SSR 框架只能与一家云供应商合作,那么你最终会被供应商锁定。幸好,像 Remix 和 Astro 这样的框架是“服务器无关(server agnostic)”的,所以你可以使用自建的服务器,或者借助适配器,在你选择的云供应商中启用 SSR。
一个反复出现的问题就是“无休无止的加载器(spinner-geddon)”,每当导航到一个新的“页面”时,都会出现一个加载器动画,表示正在加载数据,只有在成功完成 HTTP 请求后,页面才会充满内容。
SPA 对搜索引擎优化(Search Engine Optimization,SEO)也不够友好,因为在谷歌看来,页面是空白的。当谷歌抓取网页时,它不会等待 HTTP 请求完成,而是直接查看网页中的内容,即 HTML,如果没有 HTML,谷歌又如何对网页进行排名呢?
正因为如此(以及其他的一些原因),React 应用程序的开发已经转向服务器端渲染。但是,虽然上述两个问题听起来都很严重,但事实真的如此吗?
开发人员的经典回答很可能是:这要看具体的情况!确实如此,我现在给你们讲一个我几年前创建 SPA 的小故事,你们可以自行判断。
时间倒回到 2018 年,我受雇于一家“技术咨询”公司,该公司负责为伦敦的一家大型金融机构进行“数字化转型”。
我的第一个项目是构建一个基于浏览器的解决方案,以取代一个过时的授权软件,该软件已经无法完成其职责,而且还在耗费公司的资金。这个应用程序仅供内部使用,只有三个用户,分别是 Margaret、Celia 和 Evelyn,她们是一个令人愉悦的团队,虽然已经接近退休年龄,但是在公司中发挥着重要的作用。
我创建应用程序耗费了八周时间,它仅使用客户端 HTTP 请求从 API 获取数据,具有身份验证功能,使用现有的 Azure DevOps 流水线进行部署,没有经过搜索引擎优化。
Margaret、Celia 和 Evelyn 非常喜欢这个应用,她们不介意偶尔出现的“加载器动画”,因为这个应用解决了她们的问题。它也为公司解决了一个问题,即不再需要昂贵的软件许可。我有可靠的消息说,这款软件至今仍在使用,而且最初的用户 Margaret、Celia 和 Evelyn 都已经退休了。
我认为是这样的,有很多内部应用永远不会与外部世界接触,也不需要由 React 驱动的更现代的 SSR 框架所提供的任何功能。但是,既然 React 文档不再推荐使用 CRA,那么如果你现在要构建 SPA,那还能使用什么呢?
Vite 可以与 React 一起使用,并可以作为 Webpack(CRA 使用的模块打包器)的更现代的替代方案。
“Vite 是一个构建工具,旨在为现代 web 项目提供更快、更精简的开发体验。”我想把本文做成一个教程,但发现这完全没有必要。
Vite 文档在“Scaffolding Your First Vite Project”部分提供了你需要了解的所有内容。根据 CLI 的提示,你可以在大约 20 秒的时间内创建并运行一个 React 应用。
从上面你可以看到,Vite 不仅是构建 React 应用的最佳选择,它还适合与其他框架一起使用。
简而言之,就是打包。
在开发应用程序时,代码会被分割为更小的模块。这使得特性更易于开发,并允许应用的不同组成部分可以共享通用代码。但是,在某些时候,所有的这些模块需要打包在一起,形成一个巨大的 JavaScript 文件。浏览器需要这个巨大的 JavaScript 文件来运行应用程序。
每当保存文件时都会进行打包(在开发过程中会发生成千上万次)。使用 Webpack 等工具,打包出的文件必须“拆除”并重建,这样才能反映出变化。只有在打包步骤完成后,浏览器才会刷新,进而让开发人员真正看到自己的变更。
随着应用程序的发展,会有越来越多的 JavaScript 添加进来,打包的工作量也会越来越大。随着时间的推移,打包步骤会变得越来越长,并可能真正影响开发人员的效率。Vite 利用原生 ES 模块和 HMR(热模块替换)解决了这个问题。
有了 Vite,当文件“保存”时,打包文件中只会更新发生变化的模块。这将大大加快打包步骤,并带来更高效、更愉快的开发体验。
使用 Vite 还有许多其他好处,文档中已有明确说明,请参阅 Why Vite。
世界就这样,旧的不去,新的不来……但是,React SPA 的传统依然会持续!
当然,在很多情况下,SPA 并不是最合适的选择。但是,在 SPA 或 SSR 的问题上,并不是“非此即彼”,而是 “兼而有之”。
声明:本文由 InfoQ 翻译,未经许可禁止转载。
微信扫码关注该文公众号作者