SPA 单页Web应用介绍——w3cdream|前端学习-开发

'I'm W3cdream,创造',前·所·未·有
SPA 单页Web应用介绍

发布作者:萧强   发布时间:2015-09-18   阅读次数:3986

定义

单页 Web 应用 (single-page application 简称为 SPA) 是一种特殊的 Web 应用。它将所有的活动局限于一个Web页面中,仅在该Web页面初始化时加载相应的HTML、JavaScript 和 CSS。一旦页面加载完成了,SPA不会因为用户的操作而进行页面的重新加载或跳转。取而代之的是利用 JavaScript 动态的变换HTML的内容,从而实现UI与用户的交互。由于避免了页面的重新加载,SPA 可以提供较为流畅的用户体验。

优缺点

单页Web程序的出现是富客户端发展的必然结果,但是该技术也是有些局限性,所以采用之前需要了解清楚它的优缺点。

优点:

  1. 良好的交互体验

    用户不需要重新刷新页面,获取数据也是通过Ajax异步获取,页面显示流畅。

  2. 良好的前后端工作分离模式

    单页Web应用可以和RESTful规约一起使用,通过REST API提供接口数据,并使用Ajax异步获取,这样有助于分离客户端和服务器端工作。更进一步,可以在客户端也可以分解为静态页面和页面交互两个部分。

  3. 减轻服务器压力

    服务器只用出数据就可以,不用管展示逻辑和页面合成,吞吐能力会提高几倍;

  4. 共用一套后端程序代码

    不用修改后端程序代码就可以同时用于Web界面、手机、平板等多种客户端;

缺点:

  1. SEO难度较高

    由于所有的内容都在一个页面中动态替换显示,所以在SEO上其有着天然的弱势,所以如果你的站点对SEO很看重,且要用单页应用,那么就做些静态页面给搜索引擎用吧。

  2. 前进、后退管理

    由于单页Web应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理,当然此问题也有解决方案,比如利用URI中的散列+iframe实现。

  3. 初次加载耗时多

    为实现单页Web应用功能及显示效果,需要在加载页面的时候将JavaScript、CSS统一加载,部分页面可以在需要的时候加载。所以必须对JavaScript及CSS代码进行合并压缩处理,如果使用第三方库,建议使用一些大公司的CDN,因此带宽的消耗是必然的。

框架

AngularJS

AngularJS是一个 MV* 框架,最适于开发客户端的单页面应用。它不是个功能库,而是用来开发动态网页的框架。它专注于扩展HTML的功能,提供动态数据绑定(data binding),而且它能跟其它框架(如jQuery)合作融洽。

如果你要开发的是单页应用,AngularJS就是你的上上之选。Gmail、Google Docs、Twitter和Facebook这样的应用,都很能发挥AngularJS的长处。但是像游戏开发之类对DOM进行大量操纵、又或者单纯需要极高运行速度的应用,就不是AngularJS的用武之地了。

Avalon

Avalon 是一个 MV* 框架,国内迷你简单易用的MVVM框架


平时喜欢做点小页面来玩玩,并且一直采用单页面应用(Single Page Application)的方式来进行开发。这种开发方式是在之前一年做的一个创业项目的经验和思考,一直想写篇博客来总结一下。

个人认为单页面应用的优势相当明显:

  1. 前后端职责分离,架构清晰:前端进行交互逻辑,后端负责数据处理。
  2. 前后端单独开发、单独测试。
  3. 良好的交互体验,前端进行的是局部渲染。避免了不必要的跳转和重复渲染。

当然,SPA也有它自身的缺点,例如不利于搜索引擎优化等等,这些问题也有其相应的解决方案。

下面要介绍的这种方式可以说是一种模式或者工作流,和前端使用什么框架无关,也和后端使用什么语言、数据库无关。不能说是The Best Practice,我相信经过更多人的讨论和思考会有A Better Practice。:)

概览

下图展示了这种模式的整个前后端及各自的主要组成:

overview

看起来有点复杂,接下来会仔细地对上面每一个部分进行解释。看完本文,就应该能理解上图中的各部件之间的交互流程。

前端架构

把上图的前端部分单独抽出来进行研究:

simple-front

前端中大致分为四种类型的模块:

  1. components:前端UI组件
  2. services:前端数据缓存和操作层
  3. databus:封装一系列Ajax操作,和后端进行数据交互的部件
  4. common/utils:以上组件的共用部件,可复用的函数、数据等

components

component指的是页面上的一个可复用UI交互单元,例如一个博客的评论功能:

comment

我们可以把博客评论做为一个组件,这个组件有自己的结构(html),外观(css),交互逻辑(js),所以我们可以单独做一个叫comment的component,由以下文件组成:

  1. comment.html
  2. comment.css
  3. comment.js

(每个component可以想象成一个工程,甚至可以有自己的README、测试等)

components tree

一个component可以依赖另外一个component,这时候它们是父子关系;component之间也可以互相组合,它们就是兄弟关系。最后的结果就类似DOM tree,component可以组成components tree。

例如,现在要给这个博客添加两个功能:

  1. 显示评论回复。
  2. 鼠标放到评论或者回复的用户头像上可以显示用户名片。

comments-replies-poputbox

我们构建两个组件,reply和user-info-card。因为每个comment都要有自己的回复列表,所以comment组件是依赖于reply组件的,comment和reply组件是嵌套关系。

而user-info-card可以出现在comment或者reply当中,并且为了以后让user-info-card复用性更强,它应该不属于任何一个组件,它和其他组件是组合关系。所以我们就得到一个简单的componenets tree:

components-tree

components之间的通信

怎么可以做到鼠标放到评论和回复的用户头像上显示名片呢?这其实牵涉到组件之间是如何进行通信的问题。

最佳的方式就是使用事件机制,所有组件之间可以通过一个叫eventbus通用组件进行信息的交互。所以,要做到上述功能:

  1. user-info-card可以在eventbus监听一个user-info-card:show的事件。
  2. 而当鼠标放到comment和reply组件的头像上的时候,组件可以使用eventbus触发user-info-card:show事件。


看着图来,我们总结一下整个前后端的交互流程

  1. 前端向服务端请求第一个页面,后端渲染返回。
  2. 前端加载各个component,components从services拿数据,services通过databus发送Ajax请求向后端取数据。
  3. 后端的CGI接收到前端databus发送过来的请求,处理数据,调用business操作数据库,返回结果。
  4. 前端接收到后端返回的结果,把数据缓存到service,component拿到数据进行前端组件的渲染、显示。

工作流

一个好的工作流可以让开发事半功倍。上面的这种单页面应用也有其相应的一种开发工作流,当然这种工作流也适合非单页面应用:

  1. 进行产品功能、原型设计。
  2. 后端数据库设计。
  3. 根据产品确定前后端的API(or RESTful API),以文档方式纪录。
  4. 前后端就可以针对API文档同时进行开发。
  5. 前后端最后进行连接测试。

前后端分离开发。建议都可以采用TDD(测试驱动开发)的方式来单独测试、单独开发(关于Web APP测试这一块可以单独进行讨论研究),提高产品的可靠性、稳定性。


常用昵称:萧强,全端布道者

姓名:“刘晓强”,W3CDream创始人,目前就职于易点付。专注于web前端和移动端方面知识的研究,熟练掌握photoshop和AI,喜爱Flat UI设计和Metro UI风格,熟练掌握CSS3+HTML5技术、LESS CSS和Sass CSS,还有jQuery框架方面及一些前端框架bootstrap响应式设计等。新浪微博
友荐云推荐

前端资源

热点文章

新闻资讯

标签云

友情赞助