【译】下一代web框架的转变

2024-04-05  本文已影响0人  涅槃快乐是金

Web前端由在25年前的技术组成。HTTPHTMLCSSJS都是在九十年代中期首次标准化的。从那时起,网络发展成为一个无处不在的应用平台。随着网络的发展,用于开发这些应用的架构也在不断演进。如今,有许多用于构建网络应用的核心架构。目前由网络开发人员使用的最流行的架构是单页面应用程序(SPA),但我们正在转向一种新的、改进的用于构建网络应用程序的架构。

<a><form> 元素从一开始就存在。链接用于让浏览器从服务器获取内容,而表单用于让浏览器将内容发送到服务器(并得到返回内容)。有了这种从一开始就包含在规范中的双向通信,就可以在网络上永远创建功能强大的应用程序。

以下是主要的架构(按照流行程度的时间顺序排列):

Web 开发的每种架构都有其优点和痛点。最终,痛点变得足够严重,以至于促使转移到下一个架构,该架构带来了自己的折衷方案。

无论我们如何构建应用程序,我们几乎总是需要在服务器上运行代码(值得注意的例外包括像 Wordle 这样的游戏,它们将游戏状态存储在本地存储中)。区分这些架构的一种方法是代码的存放位置。让我们依次探讨每种架构,并观察代码位置随时间的变化。在讨论每种架构时,我们将特别考虑以下代码用例:

自然地,Web应用程序还有更多部分,但这些部分是最常移动和我们作为 Web 开发人员花费大量时间的部分。根据项目规模和团队结构,我们可以在所有这些代码类别中工作,也可以只在其中一部分中工作。

多页面应用程序(MPAs)

在早期,这是基于当时网络浏览器功能的唯一可行的架构。



在多页面应用程序中,我们编写的所有代码都驻留在服务器上。客户端的用户界面反馈代码由用户的浏览器处理。

MPA 架构

注意:成功的更新应该发送重定向响应,而不仅仅是新的 HTML。否则,您的历史堆栈中将存在 POST请求,点击返回按钮将再次触发 POST请求(曾经想过为什么应用程序有时会说“不要点击返回按钮!!”是的,就是这个原因。它们应该响应重定向)。

MPA 的优缺点

MPA的思维模型很简单。我们当时并不太喜欢它。虽然在请求/响应循环的时间内处理了一些状态和复杂流程,但大多数情况下都是在请求/响应周期内完成的。

这种架构的不足之处在于:

值得注意的是,随着即将推出的页面跳转 APIMPA对于更多场景来说将变得更加可行。但对于大多数网络应用程序来说,这还不够。无论如何,在当时,这个问题远未被标准委员会和用户所关注!

逐步增强型多页面应用程序(PEMPAs)

渐进式增强是我们的 Web 应用程序应该在所有Web 浏览器上都是功能性和可访问的,然后利用浏览器具有的任何额外功能来增强用户体验的理念。该术语由Nick FinckSteve Champeon 在 2003 年提出。说到浏览器的功能...

XMLHttpRequest最初是由微软的 Outlook Web Access团队在 1998 年开发的,但直到 2016 年才标准化(你能相信吗!?)。当然,在这之前,这并没有阻止浏览器供应商和 Web 开发人员。AJAX一词在 2005 年被普及,并且许多人开始在浏览器中进行 HTTP 请求。企业建立在这样一个理念上:我们不必再次返回服务器以获取更新 UI 所需的数据,而只需少量数据即可。有了这个,我们就可以构建逐步增强型多页面应用程序:

"哇!" 你可能会想,“等一下... 这些代码都从哪来的?”现在我们不仅从浏览器那里接管了 UI 反馈的责任,而且还将路由、数据获取、数据变异和渲染逻辑以及我们已经在服务器上拥有的内容都添加到了客户端上。“这是怎么回事?”

好吧,这就是事实。渐进式增强背后的理念是我们的基线应该是一个功能性的应用程序。特别是在 2000 年代初期,我们无法保证用户使用的浏览器能够运行我们新的 AJAX功能,或者他们是否处于足够快的网络上以在与应用程序交互之前下载我们的 JavaScript。因此,我们需要保持现有的 MPA 架构不变,并仅使用 JavaScript来增强用户体验。

也就是说,根据我们所谈论的增强级别,我们可能确实需要在我们几乎所有的类别中编写代码,除了持久性(除非我们需要离线模式支持,这确实很好,但不是行业标准做法,因此没有包含在图表中)。

此外,我们甚至必须在后端添加更多代码来支持客户端将进行的AJAX请求。所以,在网络的两端都有更多的内容。

这是 jQueryMooTools等的时代。

PEMPA 架构行为
PEMPA 优缺点

通过带上客户端代码和接管 UI反馈功能,我们确实解决了 MPA的问题。我们拥有了更多的控制权,可以为用户提供更自定义的应用程序感。

不幸的是,为了给用户提供他们期待的最佳体验,我们必须负责路由、数据获取、变异和渲染逻辑。这其中存在一些问题:

单页面应用程序(SPAs)

不久之后,我们意识到如果从后端删除 UI 代码,就可以解决重复问题。所以我们就这样做了:


你会注意到这个图形几乎与 PEMPA 的图形完全相同。唯一的区别是渲染逻辑消失了。一些路由代码也消失了,因为我们不再需要为 UI 设置路由。我们剩下的只有 API路由。这是 BackboneKnockoutAngularEmberReactVueSvelte 等行业中大多数使用的策略。

SPA 架构


由于后端不再具有渲染逻辑,所有文档请求(用户在输入我们的 URL 时进行的第一次请求)都由静态文件服务器(通常是CDN)提供。在SPA的早期,HTML文档几乎总是一个空的HTML文件,其中 <body>中有一个<div id="root"></div>,用于“挂载”应用程序。然而,如今,框架允许我们使用一种称为“静态站点生成”(SSG)的技术,在构建时预渲染页面的大部分内容。


此策略中的其他行为与 PEMPA相同。现在我们主要使用fetch 而不是 XMLHttpRequest

SPA 优缺点

有趣的是,上面架构行为中与PEMPA的唯一区别是文档请求更糟糕了!那么我们为什么要这样做呢?

到目前为止,这里最大的优势是开发人员体验。这正是从 PEMPA 过渡到SPA的最初动力。没有代码重复是一个巨大的好处。我们通过各种方式来证明这种变化(DX 毕竟是UX 的一部分)。不幸的是,改进DX 对我们来说就是 SPA唯一做的事情。

我个人记得被说服SPA 架构有助于交互体验,因为 CDN可以更快地响应 HTML文档,而服务器生成HTML文档的速度则慢一些,但在现实世界的场景中,这似乎并没有什么区别(而且现代基础架构使这一点变得更不真实)。悲伤的现实是,SPA仍然存在与 PEMPA完全相同的其他问题,尽管有更现代的工具,这使得处理这些问题变得更容易。

更糟糕的是,SPA 还引入了几个新问题:

逐步增强型单页面应用程序(PESPAs)

MPA有一个简单的思维模型。SPA 具有更强大的功能。经历了 MPA阶段并在 SPA中工作的人们真正怀念我们在过去十年中失去的简单性。如果考虑到 SPA架构的动机主要是为了改善开发人员体验而不是为了PEMPAs,那么这就特别有趣了。如果我们可以以某种方式将SPAMPA合并为单一架构,以获得两者的优势,那么希望

我们将获得既简单又更有能力的东西。这就是逐步增强型单页面应用程序。

考虑到逐步增强,基线是一个功能齐全的应用程序,即使没有客户端 JavaScript也是如此。因此,如果我们的框架将渐进式增强作为核心原则,并鼓励使用它,那么我们的应用程序基础就有了简单的 MPA 思维模型的坚实基础。具体来说,是在请求/响应循环的上下文中考虑事物的思维模型。这使我们可以在很大程度上消除 SPA的问题。

这值得强调:渐进增强的主要好处不是“您的应用程序在没有JavaScript的情况下工作”(尽管这是一个不错的副作用),而是心智模型大幅简化。

为了做到这一点,PESPAs在阻止默认时需要“模拟浏览器”。因此,无论浏览器是进行请求还是进行基于 JavaScript的获取请求,服务器代码都以相同的方式工作。因此,虽然我们仍然拥有该代码,但在我们的其余代码中可以保持简单的思维模型。其中一个重要部分是,PESPAs 模拟浏览器在进行更新时重新验证页面上的数据的行为,以保持页面上的数据处于最新状态。对于MPA,我们只是进行了全页重新加载。对于PESPAs,此重新验证是通过获取请求进行的。

请记住,我们还有一个与 PEMPA相关的重要问题:代码重复。PESPAs 通过使后端UI代码和前端UI代码完全相同来解决这个问题。通过使用能够在服务器上渲染并在客户端上交互/处理更新的 UI库,我们就不会遇到代码重复的问题。

你会注意到数据获取、突变和渲染有小框。这些部分用于增强。例如,待处理状态、UI 等在服务器上没有实际位置,因此我们将在客户端运行一些代码。但即使这样,借助现代 UI 库的共存性,我们可以处理这些问题。

PESPA 架构


对于 PESPAs,文档请求实际上与 PEMPAs 几乎相同。所需的初始 HTML 将直接从服务器发送,JavaScript 也会加载以增强用户交互体验。


PESPA 优缺点

PESPAs 消除了先前架构中的大量问题。让我们逐一看看它们:
MPA 问题:

PEMPA 问题:

SPA 问题:

需要指出的是,无论是否使用客户端JavaScript, PESPA的工作方式都不会完全相同。只是大多数应用程序应该在没有 JavaScript 的情况下正常工作。而且这不仅仅是因为我们关心无 JavaScript用户体验。这是因为通过针对渐进增强,我们大大简化了我们的 UI代码。你会惊讶地发现,即使没有 JS,我们也可以做得很多,但对于一些应用程序来说,让所有UI元素都在没有客户端 JavaScript的情况下工作可能并不必要或实际。但即使我们的一些UI元素确实需要一些 JavaScript来运行,我们仍然可以获得 PESPAs 的主要优势。

区分 PESPA 的因素:

至于缺点。我们仍在发现其中的内容。但这里有一些想法和初步反馈:

许多习惯于 SPASSG的人会为现在服务器端代码运行我们的应用程序而感到遗憾。然而,对于任何真实的应用程序,我们都无法避免服务器端代码。当然,有一些用例可以使我们构建整个站点一次并将其放在 CDN 上,但我们白天工作的大多数应用程序并不适用于这种情况。

与此相关的是人们担心服务器成本的问题。这个想法是,SSG允许我们一次构建我们的应用程序,然后通过 CDN 以极低的成本为几乎无限数量的用户提供服务。这种批评有两个缺陷。

离开 SPA 的另一个常见问题是现在我们必须处理服务器端渲染的挑战。对于习惯于仅在客户端上运行其代码的人来说,这绝对是一个不同的模型,但如果我们使用已经考虑到这一点的工具,那么这几乎不是一个挑战。如果我们没有,那么确实可能是一个挑战,但是我们有合理的解决方法可以强制某些代码仅在客户端运行,同时进行迁移。

正如我所说,我们仍在发现逐步增强的单页面应用程序的缺点,但我认为目前我们可以感知到的好处是值得权衡的。

我还应该提到,即使我们已经具备了使用现有工具的 PESPA架构的能力,但同时关注渐进增强并共享渲染逻辑代码是新的。本文主要关注展示事实上的标准架构,而不仅仅是平台的能力。

一种 PESPA 实现:Remix

在推动PESPA 的大潮中,有一个专注于Web基础知识和现代用户体验的 Web框架——RemixRemix是第一个提供一切我描述的PESPA 功能的 Web框架。其他框架也可以并且正在适应 Remix的领先地位。我知道 SvelteKitSolidStart都在将PESPA原则融入它们的实现中。我想会有更多的框架效仿(再次说明,元框架很长时间以来就已经能够实现PESPA架构,但是 Remix将这种架构置于前沿,其他框架也在跟随)。当我们使用一个Web框架来实现 PESPA 时,情况是这样的:


在这种情况下,Remix充当了网络之间的桥梁。没有Remix,我们就必须自己实现这个功能才能完整地实现PESPARemix还通过一种组合式的约定和配置路由来处理我们的路由。Remix还会帮助我们处理渐进增强的数据获取和突变部分(如类似推特的按钮)以及实现诸如待定状态和乐观 UI 之类的 UI 反馈。

由于Remix内置的嵌套路由,我们也可以获得更好的代码组织(Next.js也在追求此功能)。虽然嵌套路由对于 PESPA架构并不是必需的,但基于路由的代码拆分是重要的一部分。此外,我们通过嵌套路由可以获得更细粒度的代码拆分,因此这是一个重要的方面。

Remix正展示了我们可以通过PESPA架构更快地构建更好的体验。而且,我们最终会得到这样的情况:


在不费吹灰之力地获得完美的性能 Lighthouse 分数?我要报名参加!

结论

就我个人而言,我对这种转变非常期待。在同时获得更好的用户体验和开发体验方面是一个很好的胜利。我认为这是一个重要的胜利,我对未来对我们的发展感到兴奋。作为对你完成这篇博客文章的奖励,我创建了一个仓库,演示了通过一个 TodoMVC应用程序的所有这些代码在不同时代之间的移动!你可以在这里找到它:kentcdodds/the-webs-next-transformation。希望这可以帮助一些想法更加具体化。

上一篇 下一篇

猜你喜欢

热点阅读