当前位置: 首页 > 编程日记 > 正文

为什么使用单页应用_为什么我讨厌您的单页应用

为什么使用单页应用

by Stefan Tilkov

斯蒂芬·蒂尔科夫(Stefan Tilkov)

为什么我讨厌您的单页应用 (Why I hate your Single Page App)

Okay, now that I have your attention, let me say that I don’t really hate your single page app. I just find it highly annoying, unless it is one of the very, very few exceptional cases that actually merit being developed in this style. As those are few and far between, it’s a fair assumption yours doesn’t qualify.

好的,现在我引起了您的注意,让我说我并不真的讨厌您的单页面应用程序。 我只是觉得这很烦人,除非它是真正值得以这种风格开发的极少数例外情况之一。 由于两者之间的距离很小,因此可以公平地假设您的资格不符。

Maybe your single page app is different, but the ones that I know break most of my browser’s features, such as the back and forward buttons, page refresh, bookmarking, sending a link, or opening a link in a new window or tab. They offer no way to link to something that I look at. (Oh, I know there are exceptions to this rule, but they typically require effort — a lot more than many developers are prepared to invest). They are bloated and slow to load, even though the actual information they display and the interaction they offer is very simple.

也许您的单页面应用程序有所不同,但是我所知道的那些应用程序破坏了我浏览器的大多数功能,例如后退和前进按钮,页面刷新,添加书签,发送链接或在新窗口或标签中打开链接。 它们无法链接到我所查看的内容。 (哦,我知道这条规则有例外,但是它们通常需要努力-比许多开发者准备投资的要多得多)。 尽管它们显示的实际信息和它们提供的交互非常简单,但它们却肿且加载缓慢。

Am I just an old, grumpy guy? Yes, but that’s beside the point. My point is that from an architectural perspective, most single page apps are the result of making the wrong choices and missing important opportunities.

我只是一个脾气暴躁的老家伙吗? 是的,但这不重要。 我的观点是,从体系结构的角度来看,大多数单页面应用程序都是错误选择和错过重要机会的结果。

My main beef with single page apps, or SPAs for short, is that they’re not “on the web”. In that regard, they are very similar to a SOAP web service. They have a URI, but only for the whole thing, not for all of those valuable things that are inside of it. (Again, I know you can build your SPA differently, but most people don’t.) I believe that if you build a web application, it should have a web UI that merits the name, similarly to a web service that should have something to do with the web.

我主要使用单页应用程序(或简称SPA)的原因是它们不在“网络上”。 在这方面,它们与SOAP Web服务非常相似。 它们具有URI,但仅适用于整个内容,而不适用于其中的所有有价值的内容。 (同样,我知道您可以以不同的方式构建SPA,但大多数人却没有。)我相信,如果您构建一个Web应用程序,它应该具有一个应具有名称的Web UI,类似于应该包含某些内容的Web服务。与网络有关。

If this all seems very abstract to you, think about what makes the web the web. The single most important feature of the web is that you can link to individual things. Every important concept within your application should be a possible entry point. This enables anyone, anywhere, to use it as the target of a link. The fact that a user can move forwards and backwards through the history of the things they have visited is not a bug, it’s an essential feature. It is crucial that each of those targets returns a response quickly, because any overhead you create will have to be paid for multiple times. The back and forward buttons are not supposed to navigate between applications.

如果这一切对您来说都非常抽象,请考虑一下使网络成为网络的原因。 网络上最重要的功能是可以链接到单独的东西。 应用程序中的每个重要概念都应该是一个可能的切入点。 这使任何地方的任何人都可以将其用作链接的目标。 用户可以在访问过的事物的历史记录中前进和后退的事实并不是一个错误,它是必不可少的功能。 这些目标中的每个目标都必须快速返回响应,这一点至关重要,因为您创建的任何间接费用都必须多次支付。 后退和前进按钮不应在应用程序之间导航。

I can almost hear you say: “But I don’t care about the web. I’m building an application, not a website.” To which I say: Go ahead then, build an application, using your desktop’s or mobile operating systems native toolkit, or build an applet, or a Flash or Silverlight application. That’s all fine by me. I don’t even object to you building the same thing using the browser as an application runtime. Just be aware that when you do things this way, your application is on the web just as much as if you had built it as a Java applet. Be aware of what you’re sacrificing.

我几乎可以听到您说:“但是我不在乎网络。 我正在构建一个应用程序,而不是网站。” 我要说的是:然后,使用桌面或移动操作系统的本机工具包构建应用程序,或构建小程序,Flash或Silverlight应用程序。 我很好。 我什至不反对您使用浏览器作为应用程序运行时来构建相同的东西。 请注意,以这种方式执行操作时,您的应用程序就可以在Web上使用,就像您将其构建为Java小程序一样。 请注意您要牺牲的东西。

This is where I believe people’s wrong choices come in. It seems as if for many people, building an SPA has become synonymous with building a modern web application. Anybody who criticizes this architectural approach has obviously not made the move to the modern world. I couldn’t disagree more. People choose an SPA without being aware of the downsides, including such things as frameworks that go out of maintenance, almost unmanageable complexity in client-side code, as well as performance and accessibility issues.

我认为这是人们做出错误选择的地方。对于许多人来说,构建SPA似乎已成为构建现代Web应用程序的代名词。 任何批评这种建筑方法的人显然都没有转向现代世界。 我完全同意。 人们在选择SPA时并没有意识到不利之处,包括诸如维护不力的框架,客户端代码几乎难以管理的复杂性以及性能和可访问性问题。

But more importantly, they miss out on the benefits of not choosing an SPA. They’re not aware of the benefits of the alternative. What is this alternative, then? It is to build a classic web application, including rendering server-side HTML, and use JavaScript only sparingly, to enhance browser functionality where possible. In this architectural approach, it is absolutely clear that the responsibility for actual business logic resides completely on the server. This includes the server-side state machine that governs the transitions between pages. And again, this is not a bug, but a feature: It is what enables a quick change on the server side to take effect immediately, everywhere — including the other kinds of clients that you might end up building in addition to your web UI. Business logic does not belong in the client, unless you like having to redundantly maintain the same logic in every kind of client you support (in addition to maintaining it on the server, of course — remember that you can never trust any client). From a server-side viewpoint, the best architecture you can have is the one you could (and should) have built a decade ago: following REST principles, including stateless communication and identification of resources.

但更重要的是,他们错过了不选择SPA的好处。 他们不知道替代方案的好处。 那么,这是什么选择呢? 它将构建一个经典的Web应用程序,包括呈现服务器端HTML,并仅少量使用JavaScript,以尽可能增强浏览器功能。 在这种架构方法中,绝对清楚的是,实际业务逻辑的责任完全在服务器上。 这包括控制页面之间过渡的服务器端状态机。 再说一次,这不是错误,而是一个功能:它使服务器端的快速更改可以在任何地方立即生效,包括在Web UI之外可能最终建立的其他类型的客户端。 除非您希望在所支持的每种客户端中冗余维护相同的逻辑,否则业务逻辑不属于客户端(当然,除了在服务器上维护该逻辑外,请记住,您永远不能信任任何客户端)。 从服务器端的角度来看,您可以拥有的最佳架构是您十年前(并且应该)构建的架构:遵循REST原则,包括无状态通信和资源标识。

Some people object to this because they believe that SPA gives you a better architecture. I disagree: With an SPA, your architecture typically is the one suggested by your framework because from a web perspective, your SPA is a single thing the web is concerned with. With a non-SPA approach (which I’m going to call ROCA from now on), the architecture governing your applications is the one of the web itself. Again, the fact that your server takes on the boring task of rendering HTML is an asset, not a burden. I, for one, don’t have a lot of trust in the stability and long-term maintainability of any of the currently existing, client-side JavaScript frameworks.

有些人对此表示反对,因为他们认为SPA可为您提供更好的体系结构。 我不同意:对于SPA,您的体系结构通常是框架建议的体系结构,因为从Web角度来看,SPA是Web与之相关的一件事。 使用非SPA方法(从现在开始,我将其称为ROCA ),控制您的应用程序的体系结构就是Web本身之一。 同样,服务器承担着呈现HTML的枯燥任务的事实是一种资产,而不是负担。 首先,我对任何现有的客户端JavaScript框架的稳定性和长期可维护性都不抱有任何信任。

A fantastic example of the problems created by the SPA approach is parallelization of work. If you have a team of multiple people, or God forbid, multiple teams working on the same SPA, you need to come up with a good way to support this. Instead, you can just have each of those teams build their own web application. Each of those applications can be connected to every other one built at the same time by the same organization (as well as to every other web application residing anywhere, if you want to) — in fact relying on the core strength of the web.

SPA方法产生的问题的一个很好的例子是工作并行化。 如果您有一个由多个人组成的团队,或者上帝禁止,多个团队在同一个SPA上工作,那么您需要想出一种很好的方法来支持这一点。 相反,您可以让每个团队都构建自己的Web应用程序。 这些应用程序中的每一个都可以连接到同一组织在同一时间同时构建的其他每个应用程序(如果需要,也可以连接到位于任何地方的其他所有Web应用程序),实际上是依靠Web的核心力量。

In terms of accessibility, rendering semantic HTML on the server-side provides an out-of-the-box support. There is only a limited set of things that you can do with HTML, and again this is a feature, not a bug.

在可访问性方面,在服务器端呈现语义HTML提供了开箱即用的支持。 您可以使用HTML进行有限的操作,这又是一项功能,而不是错误。

You can address some of those problems within an SPA, too. But it takes effort. With the ROCA approach, you have a well-known, extremely mature, proven architecture to rely on.

您也可以在SPA中解决其中一些问题。 但这需要努力。 使用ROCA方法,您将拥有一个众所周知的,极其成熟且经过验证的架构。

Of course, this does not at all suggest you do not use JavaScript and Ajax. I am completely aware that you cannot build a modern user interface without JavaScript to enable some in-page modification. But that is an optional enhancement, not the driving factor of your architecture. (Even from a REST perspective, using JavaScript is perfectly fine: It is actually mentioned as an optional constraint in the REST dissertation as “code on demand”. But its intended purpose is to serve as a means to extend the browser to support content it does not support natively.) In almost every case I’m aware of, your SPA has zero benefit for the user, and there are only positive sides to embracing browser features instead. You might believe there are benefits for the developer, but first of all, you should put those behind the interest of the user, and secondly, they’re mostly make-believe, especially in the long run.

当然,这根本不表示您不使用JavaScript和Ajax。 我完全知道,如果没有JavaScript来启用某些页内修改,就无法构建现代的用户界面。 但这是可选的增强功能,而不是体系结构的驱动因素。 (即使从REST的角度来看,使用JavaScript也很好:实际上,它在REST论文中作为“按需代码”作为可选约束被提及。但是其预期目的是用作扩展浏览器以支持其内容的一种手段。在我所知的几乎每种情况下,您的SPA对用户来说都是零收益,而采用浏览器功能只是积极方面。 您可能会相信对开发人员有好处,但是首先,您应该将这些利益置于用户的兴趣后面,其次,它们大多是虚构的,尤其是从长远来看。

So build your SPAs, I don’t mind, as long as I don’t have to use them. Just be aware of what it is you’re giving up.

因此,我不介意建立您的SPA,只要我不必使用它们即可。 只是要知道您要放弃什么。

翻译自: https://www.freecodecamp.org/news/why-i-hate-your-single-page-app-f08bb4ff9134/

为什么使用单页应用

相关文章:

marquee实现文字移动效果;js+div实现文字无缝移动效果

1.marquee实现文字移动&#xff1a; <marquee width"220px;" scrollamount"5" onmouseover"this.stop()" onmouseout"this.start()" ><p style"letter-spacing:2px;width: 1px;">欢迎您登录拜博医疗口腔集团内部…

URAL 1203 Scientific Conference(贪心 || DP)

Scientific Conference 之前一直在刷计算几何&#xff0c;邀请赛连计算几何的毛都买见着&#xff0c;暑假这一段时间就做多校&#xff0c;补多校的题目&#xff0c;刷一下一直薄弱的DP。多校如果有计算几何一定要干掉-。- 题意&#xff1a;给你N个报告会的开始时间跟结束时间&a…

5- RAC 集合 RACTuple RACSequence

RAC 集合 RACTuple RACSequence // 0 RACTuple 就是一个数组/*RACTuple 就是一个数组*/RACTuple *tp1 [RACTuple tupleWithObjects:"5",5,1, nil];RACTuple *tp2 [RACTuple tupleWithObjectsFromArray:["11","22","33"]];NSLog(&quo…

测试开发人员与开发人员_如何升级为开发人员

测试开发人员与开发人员by Will Hughes威尔休斯(Will Hughes) 如何升级为开发人员 (How to Level up as a Developer) Being a productive developer is something you can learn through experience, books, or trial and error. But, one of the best ways to become a prod…

ORA-00959: tablespace 'PSAPTEMP' does not exist

错误 : ORA-00959: tablespace PSAPTEMP does not exist 解决办法: CREATE TEMPORARY TABLESPACE PSAPTEMP TEMPFILE E:/Oracle/ORC/sapdata3/temp_1/temp.data1 SIZE 500M REUSE AUTOEXTEND ON NEXT 100M MAXSIZE unlimited EXTENT MANAGEMENT LOCAL UNIFORM SIZE 1M;ALTER …

RAC rac_liftSelector

RAC rac_liftSelector 主要是用于线程的同步 - (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.// rac_liftSelector// 类似于dispatch_group 中的组// 多线程中的组 等所有的请求都完毕之后 去更新UIRAC…

随笔记一些莆田话

莆田话是闽南话和福州话混合的产物&#xff0c;当然也是古汉语保留至今的珍宝。很多莆田话的词语是有源可溯的。这里记录一些平常想到的又可能不为人知的词语。 莆田话——普通话解释 物件——东西 万代——很多 先生——老师&#xff08;先生白读时是老师的意思&#xff09;&a…

JavaScript库和API

by Adam Recvlohe通过亚当雷夫洛厄(Adam Recvlohe) API就像一盒巧克力 (APIs are like a box of chocolates) If you have written JavaScript for the DOM before, then you probably know how unwieldy it can get. I mean getElementById is seven syllables and 14 charac…

Hadoop 全分布模式 平台搭建

现将博客搬家至CSDN&#xff0c;博主改去CSDN玩玩~ 传送门&#xff1a;http://blog.csdn.net/sinat_28177969/article/details/54138163 Ps&#xff1a;主要答疑区在本帖最下方&#xff0c;疑点会标注出来。个人在配置过程中遇到的困难都会此列举。 实验介绍&#xff1a; 本次实…

iOS 使用fastlane自动化打包步骤

加粗样式### iOS 使用fastlane 自动打包步骤 &#xff01;参考 1 查看ruby版本信息 本机是否安装ruby ruby -v 2 安装xcode命令行工具 点击同意即可 xcode-select --install 3 安装fastlane 键入如下命令 sudo gem install fastlane -NV4 使用 1 打开终端 cd 进入到要打包的…

今天开始搞CentOS 7

今天开始搞CentOS 7,安装过程很顺利&#xff0c;界面相当友好。转载于:https://www.cnblogs.com/lixd/p/3868649.html

java ruby_Java,Ruby和Go,我的天哪!

java rubyFree Code Camp has focused 100% on full stack JavaScript since we started 17 months ago. We’ve taught JavaScript on the front end, JavaScript on the back end (thanks to the powerful Node.js framework) — and even JavaScript as a database querying…

http和https的区别 与 SSL/TLS协议运行机制的概述

http和https的区别 与 SSL/TLS协议运行机制的概述 参考1 1 http 是不使用的SSL/TSL的通信通道 窃听风险&#xff1a;第三方获取通信内容篡改风险&#xff1a;修改通信内容冒充风险&#xff1a;冒充他人身份参与通信 2 SSL/TSL 协议应运而生 客户端先向服务器端索要公钥&am…

Babel 相关资料

Babel online editorBabel Plugin Handbookbabeljs usage options转载于:https://www.cnblogs.com/skating/p/6125227.html

php中this,self,parent三个关键字

phpfunctionclass语言cthis,self,parent三个关键字从字面上比较好理解,分别是指这、自己、父亲。this是指向当前对象的指针(姑且用C里面的指针来看吧) self是指向当前类的指针 parent是指向父类的指针(我 们这里频繁使用指针来描述&#xff0c;是因为没有更好的语言来表达)根据…

大量数据转移_大量数据

大量数据转移by BerkeleyTrue由BerkeleyTrue 大量数据 (A Flood of Data) Free Code Camp’s data has been doubling each month, thanks to a flood of highly-active campers. This rising tide of data has exposed several weaknesses in our codebase.由于大量活跃的露营…

约瑟夫问题总结

题解在代码里~ #include <iostream> #include <iomanip> #include <list> using namespace std;int main() {int n, k, f[100];n 12; cin>>k;//链表做法,复杂度O(n*k)list <int> L;for(int i 1; i < n; i) f[i] i, L.push_back(i);list<…

iOS中的死循环

关于死循环 自己方法里面调用自己 在 vc 中的 viewDidLoad 方法中调用 [self viewDidLoad] 会导致程序崩溃。 原因是&#xff1a; 内存溢出。 函数调用栈&#xff0c; 函数调用的时候&#xff0c;sp 栈顶指针寄存器减对应的内存空间&#xff0c;栈内存开启对应的内存空间&…

机器学习算法基础知识

在我们了解了需要解决的机器学习问题的类型之后&#xff0c;我们可以开始考虑搜集来的数据的类型以及我们可以尝试的机器学习算法。在这个帖子里&#xff0c;我们会介绍一遍最流行的机器学习算法。通过浏览主要的算法来大致了解可以利用的方法是很有帮助的。 可利用的算法非常之…

javascript_JavaScript疲劳疲劳

javascript“The Universe is under no obligation to make sense to you.” — Neil deGrasse Tyson“宇宙没有义务对您有意义。” —尼尔德格拉斯泰森 Yes, JavaScript development is complicated.是的&#xff0c;JavaScript开发很复杂。 Yes, it will continue to get mo…

TCP/IP基础概念及通信过程举例

TCP/IP基础概念及通信过程举例 出现 上个世纪60年代&#xff0c;由于中央集中式网络的容灾性较弱&#xff0c;以美国国防部为中心的一家组织研究出分组交换网络。后来为了验证分组交换技术的实用性&#xff0c;ARPANET出现了&#xff0c;并且在3年内逐渐发展&#xff0c;由4个节…

iOS 利用dSYM定位crash

What is dSYM &#xff1f; xCode 的每一次编译都会生成一个dsym文件&#xff0c;在其内部存储了16进制函数地址的映射。 在App实际执行的二进制文件中&#xff0c;是通过地址来调用方法&#xff0c;所以在App Crash 的时候&#xff0c;第三方工具会抓到函数崩溃调用栈。 通过…

OCP-052 053部分答案解析

OCP~052 9. GRANT ANY OBJECT PRIVILEGE(授予任何对象权限)&#xff1a;允许被授权人将其本身不拥有的对象的对象权限授予他人&#xff0c;但不能授予自己。 10. ENABLE VALIDATE 无法输入违反约束的行&#xff0c;而且表中的所有行都符合约束 DISABLE NOVALIDATE 可以输入任何…

您的用户界面是您产品不会因心灵感应而谦卑的补偿

by Morten Just由Morten Just 您的用户界面是您产品不会因心灵感应而谦卑的补偿 (Your UI is your product’s humble compensation for not being telepathic) 拿一些产品&#xff0c;然后继续问“这是要补偿什么&#xff1f;” 最终您将得到相同的答案。 这个答案可能就是为…

9、 Struts2验证(声明式验证、自定义验证器)

1. 什么是Struts2 验证器 一个健壮的 web 应用程序必须确保用户输入是合法、有效的.Struts2 的输入验证 基于 XWork Validation Framework 的声明式验证&#xff1a;Struts2 提供了一些基于 XWork Validation Framework 的内建验证程序. 使用这些验证程序不需要编程, 只要在一个…

java中使用队列:java.util.Queue

在java5中新添加了java.util.Queue接口&#xff0c;用以支持队列的常见操作。该接口扩展了java.util.Collection接口。Queue使用时要尽量避免Collection的add()和remove()方法&#xff0c;而是要使用offer()来添加元素&#xff0c;使用poll()来获取并移出元素。它们的优点是通过…

xCode BuildSetting 设置

一 编译选项设置 1 Optimization Level 编译器的优化级别 编译策略是对代码编译过程的优化,优化后的代码效率比较高&#xff0c;但是可读性比较差&#xff0c;且编译时间更长。 release模式设置为Fastest, Smallest[-Os] Debug模式设置为None 设置参数None编译器不会尝试优…

react绑定this_React绑定模式:处理“ this”的5种方法

react绑定thisJavaScript’s this keyword behavior has confused developers for ages.JavaScript的this关键字行为使开发人员困惑了很长时间。 There are at least five ways to handle the this context in React. Let’s consider the merits of each approach.在React中至…

php 文件限速下载代码

<?php include("DBDA.class.php"); $db new DBDA(); $bs $_SERVER["QUERY_STRING"]; //获取由提交界面传过来的参数 $bss substr($bs,3); //截取 后面的值$sql "select video from shangpin where id{$bss}"; //获取视频文件路径 $s…

【Java】Linux下安装配置Oracle JDK 1.7版本

1 环境 Vmware虚拟机中的Ubuntu 12.04 32位系统 2具体安装步骤 ①下载最新的jdk包 注意jdk区分32位版本和64位版本&#xff0c;要与Ubuntu兼容才行 下载地址 http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html ②创建一个目录&#xff0c;…