我的编程旅程始于二十多年前,那时 JavaScript 远未达到如今的水平,开发者主要关注的是 Microsoft Internet Explorer。那时候我最自豪的成就之一是编写了一些代码,让用户能够完全在客户端上添加和删除表格行。我们称之为 DHTML。许多开发者现在可能已经忘记了它,或者从未听说过它的存在。

几年后,AJAX 的出现彻底改变了我们对 web 开发的思考方式。AJAX 的出现标志着 web 开发的重大转变,将更多的逻辑从服务器转移到客户端,这一转变并非没有原因。

客户端渲染

这一转变的动力来自两个关键因素:JavaScript 语言的进步和浏览器功能的提升。例如,JavaScript 模块大大增强了关注点的分离,使代码更加易于维护。同时,Local Storage API 的引入也成为了游戏规则的改变者。

客户端渲染带来了许多好处,其中最显著的就是提升了响应速度,大大改善了用户体验。将交互保持在本地,避免了服务器的往返,使用户体验变得明显更快。

我之前提到了 Local Storage API。它与 Web Workers 一起,使离线功能成为可能,这是以前浏览器无法提供的。我记得开发过使用 Java Web Start(现在称为 OpenWebStart)的应用程序,这些程序在下载时需要服务器连接,但在离线时也能正常工作。当时,这是为数不多的提供这种功能的技术之一。现在,我们在浏览器中也能直接实现类似的功能!

将逻辑迁移到用户机器上的另一个好处是减少了服务器的计算负担。这不仅提高了性能,还降低了云计算成本。

一些组织见解

与这些技术进步并行的是移动设备的崛起。许多公司将其应用程序拆分为客户端 web 应用和服务器 API 以适应这种变化。随着原生应用的出现,这种方法成为了常态,并且往往被视为理所当然。

这种关注点分离具有深远的影响。鉴于客户端技术变化的快速步伐和其不断增长的复杂性,一个开发者几乎不可能从头到尾处理整个用例。因此,大多数组织将开发人员分为前端和后端团队。每个团队在其领域内迅速行动。然而,当需要进行集成时,就会出现问题,导致调整,也就是所谓的 bug 修复。这个过程可能很麻烦,因为它需要识别问题所在并将其分配给合适的团队。更不用说随之而来的责备游戏了。

这种客户端和服务器之间的人为分离对于许多中小型组织来说是一个不必要的障碍。一个简单的 web 应用程序,配以调整良好的 CSS,通常就足够了。这就是为什么我非常喜欢 Vaadin 框架的原因。使用 Vaadin,你的开发人员只需要学习一个技术栈,使用一种编程语言和少量的 API。每个开发人员都可以同时处理后端和 UI,使整个过程更简单、更具成本效益。然而,像微服务一样,群体心理依然很强。

服务器端渲染的兴起

与任何新技术一样,早期采用者迅速跟进,技术获得 traction,并且随着时间的推移出现问题。客户端渲染也不例外。

随着越来越多的代码迁移到客户端,一些软件开始触及浏览器所能处理的极限,尽管浏览器已有改进。在浏览器开始渲染页面之前,它必须下载所有必要的资源——主要是 JavaScript 库。为了缓解这一问题,我们对库进行了压缩,并增加了并行下载的数量。曾经,我们甚至不得不创建虚拟子域名,因为浏览器在从单一域名进行并行下载的数量上存在严格限制。

我们开发了复杂的技术来欺骗用户,让他们觉得页面已经快速加载,即使页面并没有完全渲染。这涉及到初步只管理可见部分页面,并将其余部分延迟到必要时再处理。许多这些技术还依赖于浏览器的引擎,而浏览器的引擎经常变化。这导致了“货运崇拜”编程和在本应是工程的领域出现了黑魔法。

另一个重要的问题是 SEO。爬虫和索引页面的机器人是为更简单的 Web 设计的,其中页面是服务器端渲染的。尽管 Google 和其他公司在改进 JavaScript 知晓的机器人方面取得了一些进展,但对于 SEO 来说,服务器端渲染仍然无可比拟。

最后,服务器端渲染改善了初始加载时间,并简化了开发组织结构。

我们必须认识到客户端渲染所带来的好处,但也许钟摆已经摆得太远了。是否可能拥有两全其美的方案?在行业的某些角落,冷静的头脑 prevailed,SSR 这个术语被创造出来,以描述回归我们一直在做的事情——尽管有一些现代化的改进。这个想法是利用 AJAX、JavaScript 和浏览器的改进,而避免不必要的臃肿。虽然有许多工具可用,但我经常听到 Vue.jsHTMX。最近的搜索还让我发现了 Alpine.js。我长期以来一直是 Vaadin 的支持者。

我计划在这个专注的系列中探索这些技术,通过实现一个小型待办事项应用程序来进行比较。以下是我的要求:

  • 我将从后端开发者的角度来进行。
  • 无前端构建步骤:不使用 TypeScript,不进行压缩等。
  • 后端应用程序管理所有依赖项,例如 Maven。