再见SPA?

背景

image

首屏渲染

SPA的首屏渲染堪称灾难,正如上文所说,SPA会先请求html,然后再执行里面的js。
这个过程是串行的,如果在网络环境较差的情况下会相当难熬。

SEO之类的不提了,这一点不一定有人为条件影响严重。

路由切换

路由切换时也一样,先获取到组件相关的js文件,然后执行才能开始请求接口。

首屏时间

SPA

先获取html -> 获取js -> 执行js后发起API请求(首屏渲染) -> 获取到响应后,渲染完整页面
image

SSG

获取html(有静态元素,首屏渲染) -> 获取js -> 执行js后发起API请求 -> 获取到响应后,渲染完整页面
在获取html的阶段,html内部就已经有静态元素结构了,这时候用户已经能够看到应用的结构。接下来只需要发送请求然后获取数据(这一部分是和SPA一样的)。
image
SPA和SSG的差异在于,SPA的静态元素也是通过js来生成的,由于js获取得晚,因此静态元素出现得也晚。

传统SSR

传统的SSR依然需要使用js来生成静态元素,只不过js运行在服务器上。当没有API请求,或者API请求足够快时,他渲染的首屏才会比SPA快。
传统的SSR就是下面的图的流程,可以看到,首屏是最慢的。
之所以有人说SSR快,是因为如果首屏没有API请求,那么就接近于SSG,会很快。
但是如果API请求很慢,那么他会比其他方式更加慢,因为他需要跑完整个流程才返回首屏。

image

扩展

流式SSR

传统的SSR会卡在服务器发起API请求的时间里面,然后用户一直看不到首屏。
https://svelte.dev/docs/kit/load#Streaming-with-promises
image

岛屿架构

在传统SSR中,即使是静态的网页元素,也依然需要执行js来生成(而不像SSG那样直接把静态元素写在html里面)。
岛屿架构由Astro提出,他的目的就是尽可能减少js的执行。

极致速度的追求

纯静态站点(没有API请求,最快的速度,链路最短,只需要获取html即可渲染)
半静态站点(有API请求的SSG,可以直接获取到静态html,动态内容由浏览器去获取)
流式SSR+岛屿结构(可以直接获取到静态html,动态内容由服务器去获取)
以上这三种,都可以实现最快首屏,流式SSR去掉岛屿结构,应该也大差不差,因为瓶颈是网络请求,而不是js执行(SSR的js在本地,所以也是很快的)。

如果SPA能内联js,那不是更快吗,理论上只比SSG慢一点点,因为需要使用js来构建静态元素。
image

使用流式SSR

在http1.1协议中,响应头里面必须有下面这个字段才能标识流式。
image

权衡下的选择

比较下来,好像SPA一无是处。
实际上SPA的优势就是简单。

  • 只需要考虑浏览器,不需要加判断(SSG需要判断仅浏览器使用的代码,防止构建静态元素发生错误)
  • 构建时不会生成静态元素,不会产生额外问题

SSR是最复杂的,不仅需要考虑构建(和SSG一样构建时不能访问document),服务器上执行代码的调试成本也比纯浏览器更高。
流式SSR在获取到请求时执行相关js代码,能够较其他方式更早地向API发起请求。
然而这段时间并没有那么紧迫,而且SSR提升了调试的难度。
在简单的应用中,这当然没什么。当应用复杂时,任何一点额外的复杂性都可以成为压死骆驼的最后一根稻草。

SPA的流行就是因为简单,就像是广受诟病的Electron那样,Electron几乎在最大限度上屏蔽了操作系统的差异,让开发者少掉一些头发,未必不是好事。

posted @ 2026-01-30 17:29  魂祈梦  阅读(4)  评论(0)    收藏  举报