单页应用程序:优点和缺点 [已关闭]

Single Page Application: advantages and disadvantages [closed]

提问人:VB_ 提问时间:2/19/2014 最后编辑:VB_ 更新时间:12/13/2017 访问量:154189

问:


想改进这个问题吗?更新问题,以便可以通过编辑这篇文章来用事实和引文来回答。

7年前关闭。

我读过关于SPA及其优势的文章。我发现他们中的大多数都没有说服力。有 3 个优点引起了我的怀疑。

问题:你能作为SPA的拥护者,证明我对前三个陈述是错误的吗?

                              === ADVANTAGES ===

1. SPA 非常适合响应速度非常快的网站:

服务器端渲染很难实现所有中间体 状态 - 小视图状态不能很好地映射到 URL。

单页应用程序的特点是它们能够重绘任何部分 的 UI,而无需服务器往返来检索 HTML。这 通过将数据与数据的呈现方式分开来实现 具有处理数据的模型层和读取 从模型。

为非 SPA 保留模型层有什么问题?SPA 是否是客户端唯一与 MVC 兼容的体系结构?

2. 使用 SPA,我们不需要使用额外的查询来下载页面。

呵呵,用户在访问您的网站时可以下载多少页面?二、三?相反,出现了另一个安全问题,您需要将登录页面,管理页面等分开到单独的页面中。反过来,它与 SPA 体系结构冲突。

3.可能还有其他优势吗?别的都没听说过。.

                            === DISADVANTAGES ===
  1. 客户端必须启用 javascript。
  2. 站点只有一个入口点。
  3. 安全。

附言我从事过 SPA 和非 SPA 项目。我之所以问这些问题,是因为我需要加深我的理解。没有伤害SPA支持者的意思。不要让我多读一点关于SPA的信息。我只是想听听你对此的看法。

JavaScript 架构 客户端 单页应用程序

评论

1赞 Wiktor Zychla 2/19/2014
2. 和 3.不是问题。
1赞 Wiktor Zychla 2/19/2014
我建议,与其只阅读有关SPA的信息,不如花一些时间使用像extjs这样的实际框架。在那里的时间会得到回报,您将能够回答自己的问题。
3赞 VB_ 2/19/2014
@WiktorZychla我从事一个SPA项目。我使用 JQuery + Backbone。我还编写了一个JSP站点。我无法回答这些问题。你能吗?
3赞 Wiktor Zychla 2/19/2014
@VolodymyrBakhmatiuk:没关系,用户可以妥协的是 GUI 而不是数据,因为数据在服务器端受到保护。
6赞 Anurag Awasthi 4/3/2017
如果这个问题是基于意见的呢?我经常想知道为什么以及何时应该写 SPA?如果 SO 也允许 Pros n Cons 问题,那将会很有帮助

答:

149赞 7 revs, 3 users 68%Parv Sharma #1

让我们看看最受欢迎的 SPA 网站之一 GMail。

1. SPA 非常适合响应速度非常快的网站:

服务器端渲染并不像以前那样困难,使用简单的技术,例如在 URL 中保留 #hash,或者最近的 HTML5 pushState。使用此方法时,Web 应用的确切状态将嵌入到页面 URL 中。与 GMail 一样,每次打开邮件时,都会在 URL 中添加一个特殊的哈希标签。如果复制并粘贴到其他浏览器窗口可以打开完全相同的邮件(前提是它们可以进行身份验证)。这种方法直接映射到更传统的查询字符串,区别仅在于执行。使用 HTML5 pushState(),您可以消除并使用完全经典的 URL,这些 URL 可以在第一个请求时在服务器上解析,然后在后续请求中通过 ajax 加载。#hash

2. 使用 SPA,我们不需要使用额外的查询来下载页面。

用户在访问我的网站期间下载的页面数??当他/她打开他/她的邮件帐户时,他/她阅读了多少封邮件。我一口气读了 50 >。现在邮件的结构几乎相同。如果您将使用服务器端渲染方案,则服务器将在每个请求(典型情况下)渲染它。 - 安全问题 - 您应该/不应该为管理员/登录保留单独的页面,这完全取决于您的网站结构,例如 paytm.com 例如,制作一个网站 SPA 并不意味着您为所有用户打开所有端点,我的意思是我在我的 spa 网站上使用表单身份验证。 - 在可能最常用的 SPA 框架 Angular JS 中,开发人员可以从 Web 站点加载整个 html temple,因此可以根据用户的身份验证级别来完成。预加载所有身份验证类型的 html 不是 SPA。

3. 可能还有其他优势吗?别的都没听说过。.

  • 如今,您可以放心地假设客户端将具有支持 JavaScript 的浏览器。
  • 网站只有一个入口点。正如我之前提到的,可以维护状态,您可以根据需要拥有任意数量的入口点,但您肯定应该有一个。
  • 即使在 SPA 中,用户也只能看到他拥有适当的权利。您不必一次注入所有东西。加载 diff html 模板和 javascript 异步也是 SPA 的有效部分。

我能想到的优点是:

  1. 渲染 HTML 显然需要一些资源,现在每个访问您网站的用户都在这样做。此外,不仅渲染,主要逻辑现在都是在客户端而不是服务器端完成的。
  2. 日期时间问题 - 我只是给客户端 UTC 时间是预设格式,甚至不关心我让 javascript 处理的时区。对于我必须根据从用户 IP 得出的位置来猜测时区来说,这是一个很大的优势。
  3. 对我来说,状态在SPA中维护得更好,因为一旦你设置了一个变量,你就知道它会在那里。这给人一种开发应用程序而不是网页的感觉。这通常对制作 foodpanda、flipkart、亚马逊等网站有很大帮助。因为如果不使用客户端状态,则使用的是昂贵的会话。
  4. 网站肯定反应灵敏 - 我将举一个极端的例子,尝试在非 SPA 网站中制作计算器(我知道它很奇怪)。

来自评论的更新

似乎没有人提到套接字和长轮询。 如果您从另一个客户端注销,比如移动应用程序,那么您的浏览器 也应该注销。如果不使用 SPA,则必须重新创建 套接字连接,每次有重定向。这也应该 处理数据中的任何更新,如通知、配置文件更新等

另一种观点:除了你的网站,你的项目也会 涉及原生移动应用程序?如果是,你很可能会 将原始数据从服务器(即 JSON)馈送到该本机应用程序,然后执行 客户端处理来呈现它,对吗?所以有了这个断言, 您已经在做客户端渲染模型了。现在的问题是 变成,为什么你不应该对网站版本使用相同的模型 您的项目?有点不费吹灰之力。那么问题就变成了 是否只想为了 SEO 的好处而呈现服务器端页面,以及 可共享/可书签 URL 的便利性

评论

4赞 Jason Sperske 2/19/2014
很高兴你把它变成一个社区 Wiki 答案:)这些都是很好的观点
0赞 VB_ 2/19/2014
@Parv Sharma 请更广泛地解释为什么维护状态对 SPA 更敏感?
5赞 Ankit_Shah55 7/13/2015
您无法轻松地使用 SPA 为页面编制索引以进行 SEO 优化。
2赞 Kevin Wheeler 12/23/2015
@Ankit_Shah55 这可能不再是真的(至少对于谷歌来说,无论如何,谷歌拥有大部分搜索引擎市场份额)。请参阅 Google 的“弃用我们的 AJAX 抓取方案”。我的理解是,您不必再为 Google 做任何特别的事情来索引您的 SPA。但是,我认为您需要确保支持 pushstate,因为我认为谷歌不会索引哈希片段。
3赞 Taku 3/8/2017
似乎没有人提到套接字和长轮询。如果您从另一个客户端(例如移动应用程序)注销,那么您的浏览器也应该注销。如果不使用 SPA,则每次重定向时都必须重新创建套接字连接。这也应该适用于数据中的任何更新,如通知、配置文件更新等。
42赞 Lars Kemmann 2/19/2014 #2

1. 客户端必须启用 javascript。是的,这是 SPA 的一个明显缺点。就我而言,我知道我可以期望我的用户启用 JavaScript。如果你不能,那么你就不能做SPA,时期。这就像尝试将 .NET 应用部署到未安装 .NET Framework 的计算机上一样。

2.网站只有一个入口点。我使用 SammyJS 解决了这个问题。需要 2-3 天的时间才能正确设置路由,用户将能够在您的应用程序中创建可以正常工作的深层链接书签。你的服务器只需要公开一个端点 - “给我这个应用的 HTML + CSS + JS”端点(可以把它想象成一个预编译应用程序的下载/更新位置) - 你编写的客户端 JavaScript 将处理实际进入应用程序。

3. 安全性。这个问题并非 SPA 所独有,当您拥有“老式”客户端-服务器应用程序(使用超文本在页面之间链接的 HATEOAS 模型)时,您必须以完全相同的方式处理安全性。只是用户发出请求而不是您的 JavaScript,并且结果是 HTML 而不是 JSON 或某些数据格式。在非 SPA 应用程序中,必须保护服务器上的各个页面,而在 SPA 应用程序中,必须保护数据终结点。(而且,如果你不希望你的客户端能够访问所有代码,那么你也必须将可下载的 JavaScript 拆分为单独的区域。我只是将其绑定到基于 SammyJS 的路由系统中,这样浏览器就会根据用户角色的初始加载,只请求客户端知道它应该有权访问的内容,然后这就不再是问题了。

优势

  1. 在许多情况下,SPA 的一个主要架构优势(很少被提及)是大大减少了应用程序的“聊天性”。如果正确设计它以处理客户端上的大多数处理(毕竟是重点),那么对服务器的请求数量(阅读“破坏用户体验的 503 错误的可能性”)会大大减少。事实上,SPA 可以进行完全离线处理,这在某些情况下是巨大的

  2. 如果做得好,客户端渲染的性能肯定会更好,但这并不是构建 SPA 的最令人信服的理由。(毕竟,网络速度正在提高。不要仅凭这一点来证明 SPA 的理由。

  3. UI设计的灵活性也许是我发现的另一个主要优势。一旦我定义了我的 API(使用 JavaScript 中的 SDK),除了一些静态资源文件之外,我能够完全重写我的前端,对服务器的影响为零。尝试使用传统的 MVC 应用程序来做到这一点!:)(当您需要担心 API 的实时部署和版本一致性时,这将变得很有价值。

所以,底线:如果你需要离线处理(或者至少希望你的客户端能够在偶尔的服务器中断中幸存下来)——大大降低你自己的硬件成本——你可以假设JavaScript和现代浏览器,那么你需要一个SPA。在其他情况下,这更像是一种权衡。

评论

6赞 Strille 2/19/2014
另一个优点是,SPA 可以在 iOS 上保存为书签(“添加到主屏幕”),并以全屏模式打开它(假设您定义了正确的元标记),使其感觉像一个本机应用程序,而不是一个网页。
9赞 karantan 2/28/2015
3.在传统的MVC应用程序中同样简单。如果您使用相同的数据进行操作,则只需在应用程序的 V(视图)部分进行更改即可。这通常是模板、css 和 js。
0赞 sçuçu 4/28/2016
SPA 版本的 SO 是否可以提供指向单个问题的链接来共享,或者它会带来哪些优点和缺点,例如在 SEO(过去的问题从搜索引擎中搜索到)方面。
6赞 Matthew Whited 9/4/2016
我见过的大多数 SPA 应用程序都比服务器端应用程序更健谈。最终,您不会使用单个请求来获取数据,而是每页向服务器发出更多请求。
3赞 Vish 1/17/2015 #3

缺点: 从技术上讲,SPA的设计和初始开发是复杂的,可以避免。不使用此 SPA 的其他原因可能是:

  • a) 安全性:由于跨站点脚本 (XSS),与传统页面相比,单页应用程序的安全性较低。
  • b) 内存泄漏:JavaScript 中的内存泄漏甚至会导致功能强大的计算机速度变慢。由于传统网站鼓励在页面之间导航,因此由上一页引起的任何内存泄漏几乎都会被清除,留下更少的残留物。
  • c) 客户端必须启用 JavaScript 才能运行 SPA,但在多页应用程序中可以完全避免 JavaScript。
  • d) SPA生长到最佳大小,导致等待时间长。例如:在连接速度较慢的 Gmail 上工作。

除此之外,其他架构限制包括导航数据丢失、浏览器中没有导航历史记录日志以及使用 selenium 进行自动功能测试的困难。

链接解释了单页应用程序的优点和缺点。

评论

12赞 Jason Miller 2/24/2015
这是不正确的。a) XSS 对服务器生成的页面的影响与在客户端上生成的文档一样容易。鉴于客户端上有非常简单有效的 XSS 缓解解决方案,我会更进一步地争辩说。如果您不想允许 XSS,请不要将用户提交的内容解释为 HTML。任何体面的程序员都可以处理这个问题。使用任何可用的技术(pushState、哈希路由等)都可以轻松导航。正确构建的 SPA 的 AFT 与任何其他 Web 应用程序完全相同。你的回答总结是你不知道如何为客户构建。
0赞 Vish 3/3/2015
@JasonMiller:同意。我只是意识到摘要并不是整个博客的全部上下文。我会对它进行更改。谢谢。
6赞 garryp 8/10/2015
点 a 和 b 是完全无效的。两者都与糟糕的编程有关,而不是 SPA 的特征,而且两者都完全可以与传统网站一起使用;XSS 漏洞可能会影响您的网站,即使您不编写一行 JS。内存泄漏在服务器端和客户端一样可能。至于 c 点,在这个时代禁用 Javascript 的任何人都可能会发现使用网络通常是一个主要问题,恕我直言,这不是一个问题。
9赞 Valentin H 5/8/2015 #4

对于谷歌、亚马逊等公司来说,他们的服务器在 24/7 模式下以最大容量运行,减少流量意味着真金白银——更少的硬件、更少的能源、更少的维护。将 CPU 使用率从服务器转移到客户端是有回报的,SPA 大放异彩。到目前为止,优点超过了缺点。 因此,SPA 与否 SPA 很大程度上取决于用例。

仅举一提另一个可能不那么明显的 SPA 用例(对于 Web 开发人员而言): 我目前正在寻找一种在嵌入式系统中实现 GUI 的方法,而基于浏览器的架构似乎对我很有吸引力。传统上,嵌入式系统中的UI可能性并不多 - Java,Qt,wx等或专有的商业框架。几年前,Adobe试图用flash进入市场,但似乎并不那么成功。

如今,由于“嵌入式系统”与几年前的大型机一样强大,因此通过REST连接到控制单元的基于浏览器的UI是一种可能的解决方案。优点是,免费提供大量的UI工具。(例如,Qt要求每个售出单位的特许权使用费为20-30美元,加上每个开发人员3000-4000美元)

对于这样的架构,SPA 提供了许多优势 - 例如,桌面应用程序开发人员更熟悉的开发方法,减少服务器访问(通常在汽车行业,UI 和系统混乱是单独的硬件,其中系统部分具有 RT 操作系统)。

由于唯一的客户端是内置浏览器,因此上述缺点(如 JS 可用性、服务器端日志记录、安全性)不再重要。

评论

1赞 Matthew Whited 9/4/2016
亚马逊并不太担心带宽或请求数量。每个页面大约有 10MB 和 200 多个请求。
3赞 dam_js 6/28/2015 #5

2. 使用 SPA,我们不需要使用额外的查询来下载页面。

我仍然需要学习很多东西,但自从我开始学习SPA以来,我就喜欢它们。

这一点可能会产生巨大的影响。

在许多非 SPA 的 Web 应用中,您会看到它们仍将检索内容并将其添加到发出 ajax 请求的页面。因此,我认为 SPA 超越了考虑:如果要使用 ajax 检索和显示的内容是整个页面怎么办?而不仅仅是页面的一小部分?

让我介绍一个场景。假设您有 2 个页面:

  1. 包含产品列表的页面
  2. 用于查看特定产品详细信息的页面

假设您位于列表页面。然后,单击产品以查看详细信息。客户端应用将触发 2 个 ajax 请求:

  1. 获取包含产品详细信息的 JSON 对象的请求
  2. 请求获取将在其中插入产品详细信息的 HTML 模板

然后,客户端应用会将数据插入到 html 模板中并显示它。

然后你回到列表(没有为此做任何请求!),然后你打开另一个产品。这一次,将只有一个 ajax 请求来获取产品的详细信息。html 模板将是相同的,因此您无需再次下载。

您可能会说,在非 SPA 中,当您打开产品详细信息时,您只发出了 1 个请求,而在本方案中,我们发出了 2 个请求。是的。但是从整体角度来看,当您浏览许多页面时,请求的数量会减少。在客户端和服务器之间传输的数据也会减少,因为html模板将被重用。此外,您不需要在每个请求中下载所有页面中存在的所有 css、图像、javascript 文件。

另外,让我们考虑一下您的服务器端语言是 Java。如果您分析我提到的 2 个请求,其中 1 个下载数据(您不需要加载任何视图文件并调用视图渲染引擎),另一个下载和静态 html 模板,因此您可以拥有一个 HTTP Web 服务器,无需调用 Java 应用程序服务器即可直接检索它,无需进行任何计算!

最后,大公司正在使用 SPA:Facebook、GMail、Amazon。他们不玩,他们有最伟大的工程师研究这一切。因此,如果您没有看到优势,您最初可以信任它们,并希望在未来发现它们。

但重要的是使用良好的 SPA 设计模式。您可以使用像 AngularJS 这样的框架。不要尝试在不使用良好的设计模式的情况下实现 SPA,因为您最终可能会遇到混乱。

评论

1赞 Peter Húbek 10/13/2018
Facebook 不是一个 SPA,实际上它是一个 MPA 风格的应用程序,他们在这里和那里使用 ReactJS 进行评论、聊天等。Instagram 是启用了 PWA 的完整 SPA 页面的一个很好的示例。同样适用于亚马逊,Youtube都是MPA应用程序。
30赞 Illidan 7/11/2015 #6

SPA的一个主要缺点 - SEO。直到最近,Google 和 Bing 才开始通过在抓取过程中执行 JavaScript 来索引基于 Ajax 的页面,并且在许多情况下,页面的索引仍然不正确。

在开发 SPA 时,您将被迫处理 SEO 问题,可能是通过对所有网站进行后期渲染并创建静态 html 快照供爬虫使用。这将需要对适当的基础设施进行扎实的投资。

更新 19.06.16:

自从不久前写了这个答案以来,我在单页应用程序(即 AngularJS 1.x)方面获得了更多的经验 - 所以我有更多的信息可以分享。

在我看来,SPA 应用程序的主要缺点是 SEO,使它们仅限于“仪表板”应用程序。此外,与经典解决方案相比,缓存将面临更困难的时期。例如,在 ASP.NET 缓存非常容易 - 只需打开 OutputCaching 就可以了:整个 HTML 页面将根据 URL(或任何其他参数)进行缓存。但是,在 SPA 中,您需要自己处理缓存(通过使用一些解决方案,如二级缓存、模板缓存等)。

评论

0赞 SILENT 4/25/2016
将流量转发到单个页面比分散在几个页面上更好吗?
0赞 Illidan 5/2/2016
@SILENT - 不确定,但由于所有页面都在同一域上,我认为应该没有区别
0赞 Kalnode 12/1/2017
我不明白SEO的论点。难道你不能只在SPA中定义相同的路由,也定义服务器端,这样搜索机器人就可以很容易地抓取你的网站,同时人们也可以获得你的内容的直接URL。因此,您可能有两组模板需要维护,这很重要。如果这是一个问题,您可以尝试使用通用模板。
0赞 Illidan 12/2/2017
@MarsAndBack:不确定您说的是哪个服务器链接。如果你的意思是站点地图 - 那么它在 SPA 的情况下毫无用处:搜索引擎不执行 JavaScript(至少,这是几年前的状态),它们只下载和解析 HTML。因此,即使您准备了站点地图 - 页面也无法正确构建。
15赞 Greg Gum 7/16/2015 #7

我想证明 SPA 最适合数据驱动应用程序。当然,gmail 是关于数据的,因此是 SPA 的良好候选者。

但是,如果您的页面主要用于显示,例如服务条款页面,那么 SPA 就完全矫枉过正了。

我认为最佳点是拥有一个混合了 SPA 和静态/MVC 样式页面的网站,具体取决于特定页面。

例如,在我正在构建的一个站点上,用户登陆到一个标准的 MVC 索引页。但是,当他们转到实际应用程序时,它会调用 SPA。这样做的另一个优点是 SPA 的加载时间不在主页上,而是在应用程序页面上。主页上的加载时间可能会分散初次访问网站的用户的注意力。

这个场景有点像使用 Flash。经过几年的经验,由于负载系数的原因,仅 Flash 站点的数量下降到接近于零。但作为页面组件,它仍在使用中。

评论

1赞 Rudolf Schmidt 11/13/2017
经过多年的 Web 开发,我可以确认这一点。您应该将 SPA 和 MVC 应用程序混合在一起。你也无法得到答案。我首先将我的整个应用程序作为水疗中心,发现我的应用程序没有被谷歌正确列出。所以我搬到了 mpa,只在需要的情况下使用 spa。WordPress 也不是 SPA 和流行的框架,这是有充分理由的。
1赞 Kalnode 12/1/2017
这也是我的方法。我将 SPA 作为用户快速浏览搜索结果的主要区域,无论是在地图上还是在动态列表中。然后,在查看详细信息时,这些详细信息将作为标准服务器呈现的页面打开。我的路由既可以在 SPA 中工作,也可以作为首次加载服务器路由工作。我有重复的模板代码和路由代码,但我不在乎,这是一个必要的邪恶。
1赞 Bill Lawrence 2/10/2016 #8

在未首先定义如何解决服务器端的安全性和 API 稳定性问题之前,尽量不要考虑使用 SPA。然后,您将看到使用 SPA 的一些真正优势。具体来说,如果您使用实现 OAUTH 2.0 以确保安全性的 RESTful 服务器,您将实现两个基本的关注点分离,从而降低开发和维护成本。

  1. 这会将会话(及其安全性)移动到 SPA 上,并减轻服务器的所有开销。
  2. 您的 API 变得既稳定又易于扩展。

较早暗示,但未明确说明;如果您的目标是部署 Android 和 Apple 应用程序,那么编写一个由本机调用包装的 JavaScript SPA 以在浏览器(Android 或 Apple)中托管屏幕,则无需同时维护 Apple 代码库和 Android 代码库。

1赞 magnus 2/16/2016 #9

我知道这是一个较老的问题,但我想补充单页应用程序的另一个缺点:

如果构建以 Data 语言(如 XML 或 JSON)而不是格式语言(如 HTML)返回结果的 API,则可以实现更大的应用程序互操作性,例如,在企业对企业 (B2B) 应用程序中。这种互操作性有很大的好处,但确实允许人们编写软件来“挖掘”(或窃取)您的数据。这种特殊的缺点对于所有使用数据语言的 API 都是通用的,而对于一般的 SPA 来说却不是(事实上,要求服务器提供预渲染 HTML 的 SPA 可以避免这种情况,但代价是模型/视图分离不佳)。这种缺点所暴露的这种风险可以通过各种方式来缓解,例如请求限制和连接阻塞等。

评论

2赞 Jan Kalfus 5/8/2016
1.) 没有 API 并不意味着无法挖掘 HTML 页面。2.) 您可以在一定程度上防止滥用您的 API。3.) 通过拥有 API,您不仅可以轻松地构建网页,还可以在其上构建移动应用程序,在我看来,这大大超过了任何缺点。
1赞 magnus 5/8/2016
1. 我没有说非 API 可以阻止数据挖掘。我刚才说过,API 可以使数据挖掘更容易。2. 这就是我最后一句话所要表达的。3. 拥有 API 有很多好处,我个人更喜欢 API/SPA 组合,因为我通常遇到的大多数用例。但是,我只是想在列表中添加一个缺点(回想起来,我应该将其添加为评论而不是完整的答案)。
0赞 Jan Kalfus 5/8/2016
对不起,如果我没有误解,你没有,你说“这种互操作性有很大的好处,但确实允许人们编写软件来”挖掘“(或窃取)你的数据。如果我稍微改变一下你的句子,我也可以说“网站允许人们编写软件来”挖掘“(或窃取)你的数据。现在我不是说你的想法不正确,我同意挖矿更容易,我只是说这不是你写的;)
1赞 magnus 5/8/2016
同意。这还不够清楚。嵌入在 HTML 中的数据是可挖掘的。嵌入在 JSON/XML/etc 中的数据也是可挖掘的,只是更容易
1赞 JOP 5/11/2016 #10

在我的开发中,我发现使用 SPA 有两个明显的优势。这并不是说在传统的 Web 应用程序中无法实现以下目标,只是我看到了增量的好处,而不会引入额外的缺点。

  • 由于呈现新内容,因此服务器请求较少的可能性并不总是,甚至永远不会是 http 服务器对新 html 页面的请求。但我说潜力是因为新内容很容易需要 Ajax 调用来提取数据,但该数据可能比本身更轻,加上标记,从而提供了净收益。

  • 维护“状态”的能力。简单来说,在进入应用程序时设置一个变量,它将在整个用户体验中可供其他组件使用,而无需传递它或将其设置为本地存储模式。然而,智能地管理这种能力是保持顶级范围整洁的关键。

除了需要 JS(这对 Web 应用程序来说并不是一件疯狂的事情)之外,在我看来,其他值得注意的缺点要么不是特定于 SPA,要么可以通过良好的习惯和开发模式来缓解。

74赞 Brandon 5/26/2016 #11

我是一个实用主义者,所以我会尝试从成本和收益的角度来看待这个问题。

请注意,对于我给出的任何缺点,我承认它们是可以解决的。这就是为什么我不把任何事情看作是非黑即白的,而是成本和收益。

优势

  • 更轻松的状态跟踪 - 无需使用 cookie、表单提交、本地存储、会话存储等来记住 2 个页面加载之间的状态。
  • 每个页面上的样板内容(页眉、页脚、徽标、版权横幅等)在每个典型的浏览器会话中仅加载一次。
  • 切换“页面”时没有开销延迟。

  • 性能监控 - 双手束缚:我见过的大多数浏览器级性能监控解决方案只关注页面加载时间,例如第一个字节的时间、构建 DOM 的时间、HTML 的网络往返、onload 事件等。不会测量通过 AJAX 更新页面后加载。有一些解决方案可以让你检测代码以记录显式度量值,例如在单击链接时,启动计时器,然后在呈现 AJAX 结果后结束计时器,并发送该反馈。例如,New Relic 支持此功能。通过使用 SPA,您只将自己绑定到一些可能的工具上。
  • 安全/渗透测试 - 双手捆绑:当您的整个页面由 SPA 框架动态构建时,自动安全扫描可能难以发现链接。这个问题可能有解决方案,但同样,你限制了自己。
  • 捆绑:当您在初始页面加载时下载整个网站所需的所有代码时,很容易陷入这种情况,这对于低带宽连接来说可能表现得很糟糕。您可以捆绑 JavaScript 和 CSS 文件以尝试加载更自然的块,但现在您需要维护该映射并注意通过未实现的依赖项拉入的意外文件(恰好发生在我身上)。同样,可以解决,但要付出代价。
  • 大爆炸重构:如果你想做一个重大的架构改变,比如说,从一个框架切换到另一个框架,以尽量减少风险,最好进行增量改变。也就是说,开始使用新的,在某种基础上进行迁移,例如每页、每个功能等,然后删除旧的。使用传统的多页应用程序,你可以将一个页面从 Angular 切换到 React,然后在下一个冲刺中切换另一个页面。有了SPA,要么全有,要么全无。如果要更改,则必须一次性更改整个应用程序。
  • 导航的复杂性:工具的存在是为了帮助维护 SPA 中的导航上下文,如 history.js、Angular 2,其中大多数依赖于 URL 框架 (#) 或较新的历史 API。如果每个页面都是一个单独的页面,则不需要任何页面。
  • 弄清楚代码的复杂性:我们自然而然地将网站视为页面。多页应用通常按页面对代码进行分区,这有助于提高可维护性。

再一次,我认识到这些问题中的每一个都是可以解决的,但要付出一些代价。 但是,在某种程度上,你把所有的时间都花在了解决你本来可以避免的问题上。这又回到了好处以及它们对你有多重要。

评论

2赞 DanielCuadra 12/10/2016
我认为这个回应提供了一个非常有效的反馈,来自一个实际构建了一个大型复杂系统并经历过 SPA 带来的长期伤亡(或看起来像是这样)的人
4赞 IvanP 1/16/2017
我从这个答案中得到的是,如果你正在做任何非常严肃的事情,请避免SPA。
3赞 Qi Fan 6/22/2017
我同意。当我们进行概念验证时,SPA看起来很棒。3 年过去了,我们已经看到了这个答案中提到的每一个问题,我们将继续花费大量时间试图解决它们。框架更改不再是一种选择,我们被困在一个基本上停止开发的框架中。
1赞 Zack Macomber 8/29/2017
我直接体验了最后 4 个劣势点。我已经构建了一个 10K 的 LOC Web 应用程序,以 Angular、Bootstrap 和 PHP 为主要参与者,大约有 5K 的 Angular JS 代码。Angular 有一些非常简洁的功能,但在这一点上,我真的希望我只是使用了传统的基于页面的方法,我认为这会大大加快网站的开发速度。
1赞 Zack Macomber 10/27/2020
@Prometheus我只在应用程序的 REST API 部分的后端使用 PHP(通过 Slim Framework)。SPA 部分是使用 Angular 构建的。