为什么SSR比SPA快?反之亦然?

9

我一直在阅读关于SPA与SSR的文章,可能我理解了它们的实质,但也可能没有。我很希望有经验的人可以告诉我我的假设是否正确。

观察1)

SPA - 客户端请求www.example.com,该请求从浏览器发送到服务器。服务器返回index.html,其中只有<div id="app"></div>和javascript文件的脚本源代码。浏览器再次请求捆绑的js文件,服务器将其返回。然后返回的js文件开始执行。当编译完成后,页面就会显示给用户。

SSR - 客户端从浏览器请求www.example.com。服务器完成所有操作,进行任何api调用或其他操作,将所有内容放入html中并返回html。如果这些html具有某些样式或其他js来源,则浏览器将请求这些内容。

我的看法 - 为什么SSR更快?是因为在SPA情况下,需要下载整个网站的js文件吗?而在SSR情况下,只返回用户正在输入的特定页面的内容?

观察2)

SPA - 如果页面已加载,并且用户单击其他路由之一,它不会向服务器发出任何请求以获取HTML以向用户显示它。所有路由的js文件都已下载,因此无需向服务器发出请求,除非需要针对数据库进行某些动态数据的Ajax调用。

SSR - 这将再次向服务器发送请求以获取新页面的html文件。

我的看法 - 在这种情况下,SPA更快,即使SPA仍然需要为某些数据进行ajax请求。 Ajax请求某些数据似乎比请求下载新呈现的html更快,后者还需要在服务器上进行ajax调用。

我知道SSR对于SEO很有好处,但我只关心性能。你认为我的说法是否正确?

3个回答

8

单页面应用(SPA)

只需加载一次,自由导航。理论上听起来很不错。但初始加载时间可能会成为负担。如果您的应用程序有6个不同的屏幕,每个屏幕需要0.5秒才能加载。你宁愿每次进入新页面等待0.5秒,还是等待3秒的初始加载时间?对于大多数用户来说,任何长时间的加载时间都是不可接受的,因此通常最好逐步加载内容。

此外,对于大多数现代JS框架(angular、vuejs、reactjs等),您经常需要运行框架,在客户端浏览器内创建页面,这可能会在某些情况下引起性能问题。

服务器端渲染(SSR)

在服务器端生成所有内容,动态提供内容。对于代码分割和让用户仅加载所需内容而言,听起来更好。此外,您可以在强大的服务器上运行框架,而不是在客户端计算机/手机/冰箱上运行。

然而,正如您所述,您需要更频繁地请求更多内容。为了避免这种情况,大多数现代框架能够创建部分路由,动态加载页面片段到固定布局中,如果只有页面的一部分需要更新时,则仅更新部分内容。

但这还不是全部,介绍一下

服务工作者(Service Worker)

服务工作者和SSR非常搭配。如果您建立了缓存优先策略,那么每当用户从A页面转到B页面再转回A页面时,您将仅加载A和B应用程序片段一次。您的服务工作者将识别出您再次使用相同的片段,并从用户缓存中提取它,而不是进行新的网络请求。

这使得事情感觉非常快速。

此外,您还可以预加载内容。用户悬停在链接上?开始加载该路由中使用的应用程序片段。虽然可能只能节省几百毫秒,但当您加载小型应用程序片段时,对于用户来说,它可能感觉瞬间完成。

那么有什么限制呢?首先,如果您有一个静态应用程序,实际上可能会更糟。SPA也存在缓存,如果您的应用程序足够小,则可能不关心初始加载时间中节省的几毫秒。即使是较大的应用程序,它也主要取决于您的用户群体。

但主要是,SSR需要实际的服务器来运行应用程序。许多托管服务(如Firebase或AWS)允许您托管静态文件,就像您可以用于PWA一样,并且可以轻松地从客户端处理数据库,成本非常便宜,甚至是免费的。SSR将需要一个服务器,因此您将有增加的运行成本。


谢谢这个。我想补充一点:1)我所说的是正确的吗?2)当使用服务器端渲染时,我可以看到Nuxt.js仍会下载js文件和预生成的HTML。 它这样做的原因是,当用户第一次访问网站时,nuxt提供了已经生成的HTML,这样更快。但在后台,它仍会下载js文件,以便在更改路由链接时可以使用该下载的js,因为它已经在后台编译/下载。你认为呢? - Nika Kurashvili
它下载js文件来管理您在组件中使用的所有交互,但也能够管理DOM并在称为hydration的过程中更新其片段。否则,是的,您的观察似乎是准确的。 - Morphyish
是的,但当用户首次访问页面时,会返回预生成的HTML。为了显示该页面,不需要整个巨大的JavaScript文件。这些JavaScript文件将在第一次页面加载后导航到不同组件时更好地使用。 - Nika Kurashvili
如果您没有这些js文件,您的应用程序将不知道在导航时该怎么做。 SSR仍然不是传统的服务器,提供静态HTML页面,就像您可以从PHP服务器获取的那样。 js文件确切地跟踪已加载的内容,以最小化下一条路由的加载时间。 - Morphyish

1
关于您的第二个观察,单页应用程序不必预先下载所有内容。通过动态导入,单页应用程序可以在用户切换路由时按需下载资产。这是一种优化方式,可避免预先下载所有内容所带来的开销。
就 SSR 和 SPA 而言,SSR 通常提供更好的用户体验。通过 SSR,服务器可以发送准备好的 HTML,因此应用程序大多数时间只需要进行调度和渲染结果,仅涉及最少量的客户端逻辑。如果使用框架设计 SPA,则需要在渲染之前处理下载的大部分资产。但是,可以设计 SPA,使得在初始加载时提供最小量的代码,然后在后台下载所有剩余的资产。
SPA 可以做很多事情,但是将处理工作转移到专用服务器的能力几乎总是有益的。但是,如果您担心用户带宽或者正在开发移动应用程序,那么值得考虑使用 SPA。SSR 应用程序在这里仍然可以表现良好,但是如果您可以预先将资产放在用户设备上,则应该会减少与延迟相关的问题。
再次强调,一切都取决于设计决策,但根据我的经验,SSR 应用程序具有更好的性能和可扩展性。

0

SSR(服务器端渲染)为最终用户提供了一种感知性能改进。如果您同时使用SSR和SPA,那么SSR将为最终用户提供快速的页面展示,直到SPA启动并准备好与之交互。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接