用户:恒温/单页应用 (1)
单页应用 (SPA)是一种 网页应用程序 或 网站 ,适合于单个 网页, 目的是提供一个和桌面应用程序相似的用户体验。 在SPA中,无论是所需要的代码是HTML、 JavaScript还是CSS都在一次页面加载中获取,[1] 或者通常根据用户动作动态加载有关的资源并按需要加入到网页中。 尽管 位置的哈希 或 HTML5 历史API 可用于在应用中提供独立逻辑页的感性和导航,网页在这个过程中不会重新加载,也不控制跳转到另一个网页。[2] 和单页面应用交互通常会涉及到和网络服务器动态通信。
历史
虽然早在2003年就被讨论过了,但是单页面应用的起源还是不太清楚.[3] Stuart (stunix) Morris于2002年4月写了具有同样的目标和功能的独立网站slashdotslash.com。[4] 同年晚些时候Lucas Birdeau, Kevin Hakman, Michael Peachey和Evan Yeh在美国专利8,136,109中描述了单页面应用的实现。 [5]
JavaScript可以用于在网络浏览器中显示用户界面 (UI),运行应用逻辑,以及和网络服务器进行通信。有成熟的开源库可以用来建立一个SPA,这样可以减少开发人员不得不编写的JavaScript代码量。
技术实现
即使应用需要和服务器进行通信,还是有各种技术可用于让浏览器保持单页面。
JavaScript框架
诸如 AngularJS Ember.js, Meteor.js,ExtJS 和 React 这些网络浏览器JavaScript框架都已经采纳了SPA原则。
- AngularJS 是一个纯粹的客户端框架。 AngularJS的模板是基于双向 UI数据绑定的。 数据绑定是一种让模型变化时更新视图,和在视图变化时更新模型的自动实现的方式。 HTML模板在浏览器中被编译。 编译的阶段创建纯粹的HTML代码,然后浏览把这段HTML代码重新渲染到即时视图中去。这个步骤在后面的页面展现中重复进行。 在传统的服务器端HTML编程的中,如控制器和模型这样的概念和服务器进程进行交互来生成新的HMTL视图。 在AngularJS框架中,控制器和模型状态在客户端浏览器中被维护。 因此,新网页都能够在不和服务器交互的情况下产生。
- Ember.js 是一个基于模型-视图-控制器(MVC)软件架构模式的客户端JavaScript网络应用框架。 它把常用语言的优点和最佳实践融入到一个提供丰富的对象模型,陈述式双向数据绑定,计算属性,由Handlebars.js提供支持自动更新的模板和管理应用状态的路由等特性的框架中,让开发者能够创建可扩展的单页应用。
- Meteor.js 是专为SPAs设计的全栈(客户端-服务器)JavaScript框架。 它的特点在于相对Angular,Ember or ReactJS,引用错误:
<ref>
标签中未填内容的引用必须填写name属性 有更简单的数据绑定,使用 Distributed Data Protocol引用错误:<ref>
标签中未填内容的引用必须填写name属性 和发布/订阅模式 实时自动传播数据变化到客户端,同时还不需要开发人员来编写任何同步代码。 全栈反应堆确保所有层面,从数据库到模板都能自动按需更新。 Ecosystem包,例如 服务器端渲染引用错误:<ref>
标签中未填内容的引用必须填写name属性 处理了搜索引擎优化的问题。 - Aurelia 是一个JavaScript客户框架,用于移动设备、桌面和网络。 它是类似于AngularJS,但是更新,符合更多标准,并使用了模块化办法。 Aurelia是用下一代 ECMScript写的。
Ajax
目前正在使用的最重要的技术是Ajax。引用错误:<ref>
标签中未填内容的引用必须填写name属性 主要使用JavaScript的 XMLHttpRequest/ActiveXObject(被弃用的)对象,其他Ajax包括使用IFRAME或者脚本HTML元素。受欢迎的库像jQuery 规范化了Ajax在来自不同制造商的浏览器上的行为,进一步推广Ajax的技术。
WebSockets
WebSockets 是HTML5的规范的一部分,是一个双向有状态的实时的客户端-服务器通信技术,从性能[6]和简洁性上看是Ajax的上级。
服务器推送事件
服务器发送事件 (SSEs)是一个技术,用于服务器将初始数据传输的浏览器客户端。 一旦初始化连接建立,一个事件流保持开放状态直到客户端关闭连接。 SSEs通过传统的HTTP发送并且具有多种WebSockets缺乏的功能,诸如自动重新连、事件标识,以及能够发送任意的事件。引用错误:<ref>
标签中未填内容的引用必须填写name属性
浏览器插件
虽然这种方法已经过时,异步调用服务器也可以使用浏览器插技术,例如 Silverlight, Flash,或 Java applets。
数据传输(XML,JSON和Ajax)
发送到服务器的请求通常导致服务器返回原始数据(例如, XML 或 JSON),或者新的HTML。 在该情况下,HTML由服务器返回,JavaScript在客户更新DOM(文件的对象模型)的部分区域。引用错误:<ref>
标签中未填内容的引用必须填写name属性 当原始数据被返回时,往往是一个客户端JavaScript XML /(XSL)进程(例如返回JSON时一个模板)用于翻译原始数据为HTML,然后用其更新DOM的一部分区域。
服务器架构
轻型服务器架构
一个SPA把逻辑从服务端移动到客户端。 这导致服务器的角色演变成一个纯粹的数据API或网络服务。 这个结构转变,在某些圈子被称作"轻型服务器架构"来强调复杂性已经从服务器端移向客户端,并带来了这最终降低了整个系统的复杂性的争论。
重型有状态服务器架构
服务器在内存中保存必要的客户端所在页面的状态。 在这种方式下,当任何请求到达服务器(通常用户的行为),服务器发送适当HTML和/或带结构变化的JavaScript让客户端进入想要的新状态(常常增加/删除/更新的一部分客户端DOM)。 在同一时间,服务器上的状态也更新。 大多数的逻辑在服务器上执行,并HTML通常也在服务器上渲染。 在某些方面,服务器模拟网络浏览器,接受事件并在服务器状态上执行delta changes,并自动传播到客户端。
这种方法需要更多的服务器存储和服务器处理,但其优点是简化的开发模式,因为a)应用通常是完全在服务器编码,并b)服务器上的数据和UI共享在同一个存储空间,无需特定的C/S通信桥梁。
重型无状态服务器架构
这是一个有状态服务器方法的变形。 客户端页面通常是通过Ajax请求发送表示其目前状态的数据到服务器。通过这个数据,服务器能够重建需要修改的页面部分的客户端状态,并能生成必要的数据或代码(例如,JSON或JavaScript),返回的数据或代码会把客户端带到一个新的状态,通常是根据发起请求的客户端行为来修改页面的DOM树。
这种方法需要发送到服务端更多的数据,并且为了在服务端重建客户端页面状态,每个请求都可能需要更多的计算资源。 同时,这种做法更易于扩展,因为没有在服务端保存每个单独客户端页面数据,因此,Ajax请求能被分派给不同的服务器节点,不需要会话数据共享或服务器关联性。
本地运行
一些SPAs可以从一个使用的 文件URI结构本地文件执行。 这使用户能够从一个服务器下载SPA,然后从一个本地存储设备运行该文件,而不依赖于服务器的连通性。 如果这样一个SPA要存储和更新数据,它必须使用基于浏览器的 网络存储。 这些应用从HTML5的进步中受益。[7]
单页应用模型的挑战
因为SPA是由浏览器最初设计的无状态页面重绘模型进化出来的,一些新的挑战已经浮现。 每个这些问题都有有效的解决方案[8] :
搜索引擎优化
因为主流的网络搜索引擎[13] 爬虫缺乏JavaScript的执行,SEO(优化搜索引擎)是希望在网站上采用SPA模型的公众面临一个历史难题,。[14]
从2009年至2015年, 谷歌网站管理员中 提出并建议一个"Ajax爬虫规范"[15][16] ,为有状态的 AJAX 页面在片段标识符首字母使用的一个感叹号(#!
)。在SPA站点中必须实现特殊的行为以便搜索引擎提取相关元数据。 对不支持这种URL哈希结构的搜索引擎,SPA站点上的哈希网址保持不可见状态。 这些"散列爆炸"URIs被包括W3C的Jeni Tennison在内的一些作家认为是有问题的,因为它们使页面在那些浏览器没有开启JavaScript的人无法访问。他们还破坏 HTTP referer 头,因为浏览器是不允许在Referer头发送片段标识。[17] 在2015年,谷歌弃他们的散列的爆炸的AJAX爬取提案。[18]
或者,应用可能呈现的第一页服务器的负载和随后的网页的更新客户。 这个传统上是困难的,因为呈现代码,可能需要写在一个不同的语言或框架的服务器和客户。 使用逻辑较少的模板,截编写从一种语文到另一个,或使用相同的语言在服务器和客户可能有助于增加量的代码,可以共享。
因为搜索引擎优化的兼容性并不是微不足道的SPA,这是值得注意的水疗中心通常不使用的情况下,搜索引擎编制索引是一种要求,或可取的。 使用情况包括应用程序面的私人数据的背后隐藏着一个 身份认证 系统。 在该情况下,这些应用消费品,往往是一个经典的网页重新绘的模型用于将应用程序的着陆页和营销网站,其提供足够的元数据的应用程序出现的一击一个搜索引擎查询。 博客,支持论坛和其他传统的网页重新绘制文物往往围坐在温泉,可以种搜索引擎的有关条款。
另一个方法中使用的服务器中心网框架,如基于Java ItsNat 是呈现的任何超文本的服务器使用相同的语言和模板的技术。 在这种方法,服务器就知道精确的DOM国家在客户的任何或大或小的页面更新的要求产生的服务器,以及运输由阿贾克斯,的确切JavaScript code带来的客户网页的新的国家执行DOM方法。 开发人员可以决定哪些网页的国家必须通过可搜索蜘蛛网的搜索引擎优化的和能够产生所需的国家在装载时间产生纯HTML而不是JavaScript。 在这种情况下的ItsNat框架,这是自动的,因为ItsNat保持的客户DOM树在服务器作为一个Java W3C DOM树;渲染这DOM树在服务器生成纯HTML在装载时间和JavaScript DOM行动,阿贾克斯的请求。 这种双重性是非常重要的搜索引擎优化,因为开发者可以建立,同Java的代码和纯粹基于HTML模板所需DOM国家在服务器;在页面负载时,常规HTML是由ItsNat使这DOM状态的搜索引擎优化兼容。 为1.3版本的,[19] ItsNat提供了一个新的无国籍模式中,以及客户DOM不是在服务器上保留因为与无国籍模式中客户多国家是部分或完全重建的时服务器上处理任何Ajax请求基于需要的数据由客户发送通知服务器的流DOM状态;无国籍模式中还可以搜索引擎优化兼容的,因为搜索引擎优化的兼容性发生在装载时最初的页面不受影响状态或无国籍的模式。
有一对夫妇的解决方法,使它看起来就像网站的可搜索的。 两者都涉及创建独立HTML网页镜的内容。 服务器可以创建一个基于HTML版网站,并提供,以爬虫,或者它可以使用一个无头的浏览器,如PhantomJS运行JavaScript应用程序及输出的所得HTML。
这些都需要相当多的努力,并可以最终放弃维护头痛的大型复杂的网站。 也有潜在的SEO的陷阱。 如果服务器生成HTML被认为是太不同的SPA内容,那么该网站将被处罚。 运行PhantomJS输出HTML可以减缓的反应速度的网页,其中一些是为其搜索引擎–谷歌,特别是降级排名。[20]
客户端/服务端代码分离
一种方法来增加量的代码,可以共用服务器和客户之间是使用一种逻辑-小模板语言喜欢 胡子 或 把手的。 这种模板可以呈现不同的主语言,例如 红宝石 在服务器和 JavaScript 在的客户。 然而,仅仅共享模板通常需要工作重复的 业务逻辑 使用的选择正确的模板,并填入数据。 呈现的模板可能有负面业绩的影响时,才更新一小部分的页面,如价值的文本输入内的一个大型的模板。 更换整个模板也可能会干扰用户的选择或标位置,此处仅更新的改变价值可能不会。 为了避免这些问题,应用程序可以使用 UI数据绑定 或颗粒状 DOM 操纵,只有在更新相应的部件的网页,而不是重新呈现整个模板。
浏览器历史
有一个SPA是,通过的定义,'一个单页的',该模型休息浏览器是设计为一页历史上航行使用向前/后的按钮。 这提出了一个可用性障碍时,一种用户按下按钮回,希望前面的屏幕国家内的温泉,而是应用程序的单页卸载和以前的页面的浏览器的历史记录。
传统的解决方案用于水疗中心已经改变浏览网址的散列 段标识符 合当前的屏幕状态。 这是可以实现的JavaScript,并使网址的记录事件,以建立内的浏览器。 只要温泉能够重建相同的屏幕状态从中包含的信息URL散,预期后按钮行为是保留。
进一步解决这一问题,5说明已采 pushState 和 replaceState 提供程序访问,实际的网址和浏览器的历史。
分析
分析工具,例如 谷歌分析 依赖整个新网页载在浏览器,发起一个新的页面负荷。 温泉不以这种方式工作。
之后的第一页载,随后的所有网页和内容的改变都是内部处理的应用,这应该只是一个叫功能以更新的分析包。 没有电话所述的功能,浏览器永远不会触发一个新网页载,没有得到增加的浏览器的历史和分析软件包已经没有知道谁是做什么的网站上。
为单页面应用添加页面加载
通过使用HTML5历史API可以给SPA添加页面加载事件;这将有助于集成分析。 困难在于管理这个并确保这一切都被精确跟踪,这涉及检查缺失的报告和双入口。 一些框架为主要分析供应商中的大多数提供开源的分析集成。 开发者可以将它们集成到应用,并确保一切正常,但是没有需要从头开始做的所有的事情。
初始化加载的速度
单页应用较于基于服务器的应用都有一个较慢的首页加载。 这是因为初始化加载必须在把需要的视图在浏览器中渲染成HTML之前,把框架和应用代码拉取下来。一个基于服务器的应用程序,只需要把必要HTML推送给浏览器,减少了延迟和下载时间。
加快页加载
有一些方法可以加速SPA的首次加载,例如一种重方法是用缓存和按需懒加载模块。 但不可能避免这个事实,它需要下载的框架,至少是一些应用代码,并极可能将在浏览器展示东西前调用API获取数据。 这是一个‘要么现在付钱给我,要么以后付给我'的折衷场景。 性能和等待时间这个问题的仍然是一个开发人员必须做的决定。
网页生命周期
一个SPA在初始页面加载中完全载入,接着按需从服务器加载新页面片段替换或者更新页面区域。为避免过多的下载未使用的功能,SPA通常会逐步在需要时下载更多的功能,或是小的页面片段,或是完整的画面模块。
这样在SPA中的"状态"和传统网站"网页"存在一种类比。 因为同一页面的"状态导航"和页面导航类似,在理论上,任何基于页面的网站都可以转化为单页面,通过比较非SPA连续页面中变化的部分得到结果,在同一页面替换掉即可。
网络上的SPA做法类似于流行在原生桌面应用程序的单一的文件接口 (SDI)表现技术。
参考
- ^ Flanagan, David, "JavaScript - The Definitive Guide", 5th ed., O'Reilly, Sebastopol, CA, 2006, p.497
- ^ Fixing the Back Button: SPA Behavior using Location Hash. [2016-01-18] (美国英语).
- ^ Inner-Browsing: Extending Web Browsing the Navigation Paradigm. [2011-02-03].
- ^ Slashdotslash.com: A self contained website using DHTML. [2012-07-06].
- ^ US patent 8,136,109. [2002-04-12].
- ^ Real-Time Monitoring using AJAX and WebSockets. [2016-06-01].
- ^ Unhosted web apps.
- ^ The Single Page Interface Manifesto. [2014-04-25].
- ^ Derby. [2011-12-11].
- ^ Sails.js. [2013-02-20].
- ^ Tutorial: Single Page Interface Web Site With ItsNat. [2011-01-13].
- ^ HTML5
- ^ What the user sees, what the crawler sees. [January 6, 2014].
the browser can execute JavaScript and produce content on the fly - the crawler cannot
- ^ Making Ajax Applications Crawlable. [January 6, 2014].
Historically, Ajax applications have been difficult for search engines to process because Ajax content is produced
- ^ Proposal for making AJAX crawlable. Google. October 7, 2009 [July 13, 2011].
- ^ (Specifications) Making AJAX Applications Crawlable. Google. [March 4, 2013].
- ^ Hash URIs. W3C Blog. May 12, 2011 [July 13, 2011].
- ^ Deprecating our AJAX crawling scheme. Official Google Webmaster Central Blog. [2017-02-23] (美国英语).
|work=
和|newspaper=
只需其一 (帮助) - ^ ItsNat v1.3 release Notes. [2013-06-09].
- ^ Holmes, Simone (2015).
外部链接
- 多页面网络应用到单页Ajax接口的迁移(代尔夫特技术大学): http://arxiv.org/abs/cs/0610094
- 单页宣言界面
[[Category:网络应用程序]]