单页应用程序(SPA)介绍

原文地址:https://en.wikipedia.org/wiki/Single-page_application

单页应用程序(SPA)

一个单页应用程序(spa)是Web应用或网站通过动态重写当前页面而不是从服务器加载整个新页面来与用户交互。此方法避免了用户体验在连续页面之间,使应用程序行为更像是桌面应用程序。在spa中,要么所有必要代码HTML,javascript还有css检索带有单个页加载,或者适当的资源动态加载并且在必要时添加到页面中,通常是响应用户操作。该页不会在进程的任何位置重新加载,控件也不会转移到另一个页面,尽管位置散列或HTML 5 历史api可以用于提供应用程序中独立逻辑页的感知和重新定义。与单个页面应用程序的交互常常涉及到与Web服务器幕后。

内容


历史
术语起源单页应用虽然这个概念至少早于2003才讨论过,但尚不清楚。斯图尔特(Stunix)莫里斯2002年4月,在slashdotslash.com写了一个自包含网站,并在2002年4月有相同的目标和功能同年晚些时候,卢卡斯·Birdeau、凯文·Hakman、迈克尔·Peachey和埃文·叶描述了美国专利8,136,109中的一页应用程序。


javascript可以在web浏览器中使用,以显示用户界面(Ui),运行应用程序逻辑,并与web服务器进行通信。成熟的开源库可以用来支持构建spa,减少开发人员必须编写的javascript代码的数量。

技术途径
有各种技术可以使浏览器保留一个页面,即使应用程序需要服务器通信。

javascript框架
web浏览器javascript框架,如AngularJS,Ember.js,Meteor.js,ExtJS和反应采纳了spa原则。

AngularJS是一个完全客户端框架。AngularJS的模板是基于双向的ui数据绑定。数据绑定是当模型发生变化时,自动更新视图的方式,以及每当视图发生变化时更新模型。html模板是在浏览器中编译的。编译步骤创建纯html,浏览器将重新呈现到活动视图中。对于后续页面视图,该步骤重复。在传统服务器端html编程中,诸如控制器和模型等概念在服务器进程中交互生成新的html视图。在框架中,控制器和模型状态在客户端浏览器中维护。因此,新页面能够在没有与服务器交互的情况下生成。
Ember.js是基于模型视图-控制器(Mvc)软件架构模式的客户端javascript web应用框架。它允许开发人员创建可伸缩的单页应用程序,将常用的习惯用法和最佳实践组合到一个框架中,提供丰富的对象模型、声明式双向数据绑定、计算属性、自动更新由Handlebars.js驱动的模板以及用于管理应用程序状态的路由器。

Meteor.js是专为spa设计的一个完整堆栈(客户机-服务器)javascript框架。它具有比角、灰烬或ReactJS更简单的数据绑定,并使用分布式数据协议[7]和一个发布-订阅模式自动地将数据更改自动发送到客户端,而无需开发人员编写任何同步代码。完整堆栈响应确保所有层,从数据库到模板,在必要时自动更新自己。生态系统包,如服务器端渲染针对搜索引擎优化问题,提出了解决问题的方法。

Aurelia是一个javascript客户端框架,用于移动、桌面和web。它类似于AngularJS但是,它是更新的,更符合标准的,并且使用模块化方法。Aurelia是与下一代写的n.EcmaScript。

Vue.js(通常称为Vue;发音/vju/类似于视图)是用于构建用户界面的开放源码的渐进式javascript框架。

React(有时称作React.js或ReactJS)是javascript库建筑用户界面。它是由脸书,instagram以及一个个体开发人员和公司的社区。最大的响应优势是可访问性-基本上任何熟悉html的开发人员都可以创建反应应用程序。另一个声称优势是利用相同的技术栈创建web和移动应用程序的机会。几家公司使用了与Redux库的反应,这些响应使得开发人员能够创建复杂但可伸缩的web应用程序。

Fulcro是一个全栈库,它采用了基于数据驱动原理的netflix的是、facebook的中继以及om下一步对反应性、功能、数据驱动软件的适应。它利用了下面对原始渲染的反应,获得了该平台的所有优点,但是提供了一个类似于Redux的清晰的全堆栈模型,但是使用不变数据来获得函数式编程的优点。它有一个可插拔结构,使得能够无缝集成任何后端资源,并且区分提供支持查看器技术,允许开发人员根据现场客户会话的实际ui状态历史进行调试。WebSockets作为选项支持,并允许创建高级行为n.Meteor.js用很少的代码。

ajax
目前使用的最突出的技术是ajax。主要使用xmlhttprequest/activeX Object(不推荐的)对象从javascript中,其他ajax方法包括使用iframe或脚本html元素。流行库jquery这使得从不同厂商的浏览器中实现ajax行为正常化,进一步推广了ajax技术。

WebSockets
WebSocket是一种双向状态实时客户端通信技术,html 5规范中的一部分,性能优于ajax。而且简单。

Server-sent events
服务器发送事件(SSEs)是服务器可以启动数据传输到浏览器客户端的技术。一旦建立了初始连接,则事件流仍然打开,直到客户端关闭为止。SSEs是通过传统http发送的,并且具有各种特性,它们由于自动重联、事件id和发送任意事件的能力等设计而缺乏。

浏览器插件
虽然该方法过时了,但是也可以使用浏览器插件技术来实现对服务器的异步调用,例如silverlight,闪光,或Java小程序。

数据传输(xml、json和ajax)
对服务器的请求通常会导致原始数据(例如,xml或杰森或者是新的HTML被归还了。在服务器返回html的情况下,客户机上的javascript更新了dom的部分区域(文档对象模型)。返回原始数据时,通常是客户端javascriptxml/(XSL)进程(以及在json a的情况下)模板用于将原始数据转换为html,然后使用该数据更新dom的部分区域。

Thin server architecture
spa将逻辑从服务器移动到客户端。这会导致web服务器的角色演变成纯数据api或web服务。在某些圈子里,这种架构转换被创建了“Thin server architecture”,以突出显示复杂性已经从服务器转移到客户机,并且这一论点最终降低了系统的整体复杂性。

Thick stateful server architecture
服务器保留了页面客户端状态的必要状态。这样,当任何请求命中服务器(通常是用户操作)时,服务器将适当的html和/或javascript与具体更改发送到新的期望状态(通常是添加/删除/更新客户端dom的一部分)。同时,服务器中的状态更新。大多数逻辑都在服务器上执行,并且html通常也呈现在服务器上。在某些方面,服务器模拟web浏览器、接收事件并执行服务器状态中的delta更改,这些更改将自动传播到客户端。

该方法需要更多服务器内存和服务器处理,但优点是简化开发模型,因为该应用程序通常在服务器上进行完全编码,b)服务器中的数据和ui状态共享在同一内存空间中,无需定制客户机/服务器通信桥。

Thick stateless server architecture
这是状态服务器方法的变体。客户端页面通常通过ajax请求发送代表其当前状态的数据。使用此数据,服务器能够重构页面部分的客户状态,该页面需要修改并生成必要的数据或代码(例如,json或javascript),该页面返回客户机以使其进入新状态,通常根据驱动请求的客户端操作修改页面dom树。

此方法要求将更多数据发送到服务器,并且可能需要更多的计算资源来部分或完全地重构服务器中的客户机页面状态。同时,这种方法更容易扩展,因为服务器中没有每个客户端页面数据,因此ajax请求可以发送到不同服务器节点,而无需会话数据共享或服务器关联。

本地运行
一些spa可以使用本地文件执行文件Uri方案。这使得用户能够从服务器下载spa,并且从本地存储设备中运行文件,而无需依赖服务器连接。如果这样一个spa想要存储和更新数据,那么它必须使用基于浏览器的Web存储。这些应用程序受益于可用的进展HTML 5。

与spa模型的挑战
因为spa是一个从最初设计的无状态页面重绘模型演变而来的,但是一些新的挑战已经出现。这些问题都有一个有效的解决方案有:

客户端javascript库处理各种问题。
服务器端web框架,专门用于spa模型。
浏览器和html 5规范的演进为spa模型设计。
搜索引擎优化
由于一些流行的爬虫程序中缺少javascript执行web搜索引擎,seo(搜索引擎优化对于希望采用spa模型的网站来说,历史上给出了一个问题。

2009至2015,之间谷歌网站管理员中心建议并建议一个“ajax爬行方案”使用具有状态的片段标识符中的初始感叹号标记ajax页(#!)。特别行为必须由spa站点实现,以便搜索引擎的爬虫能够提取相关元数据。对于不支持此url哈希方案的搜索引擎来说,spa的哈希url仍然是不可见的。这些“散列”的错误被许多作家认为是问题,包括在w3c中的Jeni-因为它们使那些没有页面的人无法访问页面。javascript在浏览器中激活。他们也会打破http:/页眉作为浏览器不允许在报头中发送片段标识符。2015,谷歌拒绝了他们的hash-爆炸ajax爬行提案。

或者,应用程序可以在服务器上呈现第一个页面负载,并在客户机上进行后续页面更新。传统上来说,这是困难的,因为渲染代码可能需要在服务器上和客户机上使用不同的语言或框架编写。使用逻辑少模板,从一个语言跨编译到另一个语言,或者使用服务器上的相同语言和客户机可以帮助增加可共享的代码数量。

由于seo兼容性在水疗中并不微不足道,值得注意的是,水疗通常不会被用于搜索引擎索引是需求或理想的上下文中。使用例包括将私有数据隐藏在身份验证系统。在这些应用程序是消费品的情况下,通常使用经典的“页面重绘”模型用于应用程序登陆页和营销站点,该模型提供了足够的元数据,以便应用程序出现在搜索引擎查询中的命中。博客、支持论坛以及其他传统页面重绘工件通常都坐在spa中,可以将搜索引擎与相关术语相结合。

以服务器为中心的web框架(如基于java)的另一种方法n.ItsNat是使用相同的语言和模板技术来在服务器上呈现任何超文本。在这种方法中,服务器能够精确地了解客户机上的Dom状态,服务器上生成任何大或小的页面更新,并由ajax传输,并使用ajax传输,将客户机页面带到新状态执行dom方法。开发人员可以决定哪些页面状态必须由web蜘蛛来优化搜索引擎优化,并且能够在加载时生成所需状态,生成普通html而不是javascript。在中的框架的情况下,这是自动的,因为ItsNat将服务器中的客户机dom树作为java w3c dom树保持;在服务器中呈现这个dom树生成了简单html加载时,以及ajax请求的javascript dom操作。这种对偶性对于seo非常重要,因为开发人员可以使用相同的java代码和基于html的模板构建理想的服务器上的dom状态;在页面加载时间内,通过ItsNat生成常规html,从而使这个Dom状态优化兼容。就版本而言,ItsNat提供了一个新的无状态模式,而客户机dom并不保存在服务器上,因为使用无状态模式客户机,在处理任何ajax请求时,在服务器端部分或完全重构了Dom状态;而在通知服务器当前dom状态的客户机发送的任何ajax请求时;无状态模式也可能是seo兼容,因为seo兼容性在初始页面加载时发生,而状态或无状态模式不受影响。

有几个解决办法让它看起来像是网站是不可修改的。两者都涉及创建一个单独的html页面,这些页面反映了spa的内容。服务器可以创建一个基于html的站点版本并将其交付给爬虫,或者使用一个无头浏览器(例如PhantomJS)来运行javascript应用程序并输出由此产生的html。

这两种方法都需要相当多的努力,并且最终会给大型复杂站点带来维护性头痛。还有潜在的seo陷阱。如果服务器生成的html被认为与spa内容太不一样,那么网站将会受到惩罚。运行PhantomJS输出html可以减慢页面响应速度,这正是搜索引擎-特别是google-降低排名的一个原因。

客户机/服务器代码分区
增加服务器和客户机之间可共享代码数量的方法之一是使用以下逻辑少模板语言胡须或车把。这些模板可以从不同主机语言中呈现,例如红宝石在服务器上和javascript在客户端。但是,仅仅共享模板通常需要重复业务逻辑用于选择正确的模板并使用数据填充它们。当只更新页面的一个小部分时,模板呈现可能会产生负面的性能影响-比如在大型模板中输入文本的值。替换整个模板可能会干扰用户的选择或光标位置,而只更新更改后的值可能不会。为了避免这些问题,应用程序可以使用ui数据绑定或粒状多姆操作只更新页面的适当部分,而不是重新呈现整个模板。

浏览器历史
根据定义,spa是“一个页面”,该模型打破浏览器使用前/后按钮设计页面历史导航的设计。当用户按下按钮时,会出现可用性障碍,期望在spa中出现先前的屏幕状态,但却给出了应用程序的单个页面卸载以及浏览器历史上的前页。

传统的水疗解决方案一直是改变浏览器url的哈希值。片段标识符符合当前屏幕状态。可以使用javascript实现这一点,并导致在浏览器中构建url历史事件。只要spa能够从url散列中包含的信息恢复相同的屏幕状态,则保留预期的回按钮行为。

为了进一步解决这个问题,html 5规范已经引入推送国和replaceState提供对实际url和浏览器历史的编程访问。

分析
分析工具,如谷歌分析严重依赖于在浏览器中加载的整个新页面,该页面由新页面加载启动。温泉不会这样工作。

在第一页加载之后,所有后续页面和内容更改都由应用程序内部处理,该应用程序应该简单地调用一个函数来更新分析包。如果无法调用“函数”,浏览器就不会触发新页面加载,任何内容都不会添加到浏览器历史中,分析包也不知道谁在网站上做什么。

将页面加载添加到spa
使用html 5历史api可以将页面加载事件添加到spa中;这将有助于集成分析。管理这个困难和确保所有东西都被准确地跟踪-这包括检查丢失的报告和双条目。一些框架提供了开放源码分析集成,解决了大多数主要分析提供商。开发人员可以将它们集成到应用程序中,并确保所有工作都正常运行,但无需从头开始做任何事情。

初始载荷速度
单页应用程序的第一页负载比基于服务器的应用程序更慢。这是因为第一个负载必须在浏览器中将所需视图作为html呈现之前,才会降低框架和应用程序代码。基于服务器的应用程序只需将所需的html输出到浏览器中,从而减少延迟和下载时间。

加快页面加载速度
有一些方法可以加快spa的初始负载,比如在需要时使用大量缓存和惰性加载模块。但是,不可能避免它需要下载框架,至少需要一些应用程序代码,并且很可能在浏览器中显示某些东西之前,会命中数据api。这是“付给我现在,或付给我以后”折衷方案。性能和等待时间的问题仍然是开发人员必须做出的决定。

页面生命周期
spa完全加载在初始页面负载中,然后页面区域被替换或更新,该页面片段会根据需要加载从服务器加载的新页面片段。为了避免过度下载未使用的功能,spa将经常逐步下载更多的功能,因为它们需要,或者页面的小片段,或者完整的屏幕模块。

这样,spa和传统网站中的“页面”之间就存在着类似的现象。由于同一页中的“状态导航”类似于页面导航,理论上,任何基于页面的网站都可以转换为单个页面替换在同一页中,只有更改部分的结果比较了连续页面的非spa。

web上的spa方法类似于单文档接口(Sdi)演示技术流行于本地桌面应用程序中。
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页