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

我读过关于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的信息。我只想听听你对此的考虑。


答案 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框架Angular JS中,开发人员可以从网站加载整个html temple,以便根据用户的身份验证级别完成。所有身份验证类型的预加载 html 不是 SPA。

3.可能还有其他优势吗?不要听说其他任何消息。

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

我能想到的优点是:

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

来自评论的更新

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

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


答案 2

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

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

优势

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

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

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