前端单页应用SPA走向后端路由的三条路线


现代JavaScript 框架旨在构建单页应用程序SPA,SPA名称源于它不会返回后端服务器就能在页面之间导航的事实,因为所有路由都发生在浏览器中。
自从十多年前 SPA 出现以来,JavaScript 已经打开了 Web 体验所能达到的天花板,但它是有代价的。那些没有最好的设备或最快的网络的人付出的代价最大,当事情没有按计划那样进行时,任何人都会感受到。
3 种不同的解决方案:

  • 纯 MPA可实现最佳页面加载性能的潜力。
  • “HTML框架”最适合导航到新位置。
  • “服务器组件”最类似SPA体验。

 
多页应用程序 (MPA)
那么我们回到 PHP 和 Rails 了吗?不,我希望这不会让任何人失望。每次我们都和上次不一样。
虽然完整的服务器重新加载对于许多站点来说效果很好,但我们已经习惯了能够在 SPA 中保留客户端状态并进行更平滑的转换的好处。
MPA是让服务器处理路由,实现最佳的页面加载性能,但在浏览器中导航,大多数JavaScript框架可以自己生成一些静态页面,以保持低交互性的页面快速和轻盈。
在2010年代初,我们曾经称之为小工具的空间有了巨大的增长,但现在被称为岛屿Islands。这些独立的岛屿更有能力,因为它们可以通过最新的工具(如Astro、Slinkity和Iles)进行服务器渲染和水化。
这是一种较粗略的方法,对许多网站来说是很好的,但我们已经看到在这一领域的更复杂的工具,从一开始就考虑到这一点,如Marko或Qwik在最大的电子商务解决方案中使用。像eBay的登陆页面,报告显示使用MPA这种技术可以减少80-90%的代码大小。
 
HTML Frames
这种方式拦截所有的链接点击或表单提交,并禁用默认行为,然后请求屏幕的新位置,并在完成后替换<body>的内容。最明显的是Turbo,作为Rails的Hotwire框架的一部分。

MPA是让服务器处理路由,但在浏览器中导航,保留我们的JavaScript应用状态。当每个面板panel 加载时,我们对其进行水化,由于我们知道它只能在服务器上渲染,所以上述所有的优化都适用。
然而,现在我们需要JavaScript来协调这种过渡。许多MPA框架如果支持懒惰水化,无论如何都会加载一个小的启动加载器,但在纯MPA中,有可能不需要任何运行时。
虽然这种方法不那么重,但仍然不像SPA的顺利。
从服务器上加载HTML并替换原来的内容可能会保证应用的状态,但在DOM中没有任何当前鼠标所在焦点、没有动画、没有播放器在视频标签上的位置,等等。这就给我们带来了下一个问题。

 
服务器组件
服务器组件就像MPA一样,只不过你需要回到服务器:将页面的静态部分 "重新渲染 "为VDOM,并让浏览器接收这些变化。尽管客户端组件被保留了下来,而且静态HTML中从未改变的部分也没有被替换,但我们本质上是在谈论一种路由范式。
当你点击一个链接时,它被拦截,服务器组件的端点负责处理请求,返回新的VDOM以进行差异比较。当你执行改变数据时,更新页面上的数据时,整个页面在服务器上被重新渲染,新的VDOM表现被送回来。这很像你用MPA做的一个经典的表单帖子。
每次服务器重新渲染都要发送大量的数据,还也需要更多的协调工作。你需要在浏览器中建立一个框架。所以这种方法不一定能让你得到最快的页面加载。但它有同样的能力来消除不必要地发送到浏览器的巨大百分比的组件代码。
 
分析
这是 3 种不同的解决方案,这不仅仅是一个取代另一个:
“纯 MPA” 具有实现最佳页面加载性能的潜力;“HTML框架”是 3 种框架中最适合导航到新位置的;只有“服务器组件”才有可能与我们今天拥有的单页应用程序体验无法区分。
但是所有 3 种方法都共享相同的“导航应该如何工作”的模型。它是来自服务器的整页。
本质上,与其尝试为浏览器带来一堆昂贵的缓存逻辑,不如采取refetch first 的心态。重新加载整个页面进行渲染其实没有那么糟糕,而且无需一堆额外的客户端代码即可确保页面数据的一致性。
你见过领先的 GraphQL 客户端的规模吗?压缩后大约 40kb。只需将它和 React 放在同一个页面上,您就可以在编写一行代码之前超过任何对性能至关重要的站点的预算。
 
MPA 作为一项技术保持不变,并继续提高它们的能力,以更好地进行部分水合、更智能的延迟加载、更动态的交付(流式传输)。
“HTML框架”是一个中间步骤。随着“服务器组件”的新方法出现,尤其是非 VDOM 方法,我们将看到它们被替代。
理想的方法是让服务器组件既能够提供细粒度更新的能力,又能够为新渲染的东西发送 HTML。对于初始页面加载或任何大型导航来说,HTML渲染会更快。支持混合/部分格式可能是一个问题。