什么是单页应用呢?单页应用的全称是 single-page application,简称 SPA,它是一种网站应用的模型,它可以动态重写当前的页面来与用户交互,而不需要重新加载整个页面。单页应用的流畅性让 Web 应用更像桌面端或 Native 应用了。相对于传统的 Web 应用,单页应用做到了前后端分离,后端只负责处理数据提供接口,页面逻辑和页面渲染都交给了前端。前端发展到现在,单页应用的使用已经很广泛,目前时兴的 react、vue、Angular 等前端框架均采用了 SPA 原则。单页应用意味着前端掌握了主动权,也让前端代码更复杂和庞大,模块化、组件化以及架构设计都变得越来越重要。
2、工作原理
SPA 的一个重要实现就是改变路由时,页面不刷新。实现这个功能,通常有两种方式:使用 window.history 对象或 location.hash。
3、history 对象
window.history 包含了浏览器的历史信息,它有以下几种常用方法:
history.back():与在浏览器点击后退按钮相同;
history.forward():与在浏览器中点击按钮向前相同;
history.go(n):接受一个整数作为参数,移动到该整数指定的页面,比如 go(1) 相当于 forward(),go(-1) 相当于 back(),go(0) 相当于刷新当前页面。
html5 对 history 对象新增了 pushState() 和 replaceState() 方法,这两个方法可以往历史栈中添加数据,给用户的感觉就是浏览器的 url 改变了,但是页面并没有重新加载。pushState() 是在浏览记录中添加一个新记录,replaceState() 则是修改当前的浏览器记录,这是二者的细微差别,使用时参数的字段和含义都是一样的。
window.history.pushState(state, title, url)
state 是状态对象,可以用 history.state 读取;title 表示新页面的标题,但是现在的所有浏览器都会忽略这个字段,所以可以传 null;url 是新页面的地址,必须是和当前页面在同一个域。当用户点击浏览器上的前进和后退按钮时,或者调用上述 window.history 的 back、forward 和 go 方法,就会触发 popstate 事件。该事件只针对同一个文档,如果浏览历史的切换导致加载了不同的文档,popstate 事件将不会被触发。popstate 事件回调函数的参数中的 state 属性指向 pushState() 和 replaceState() 方法为当前页面提供的状态,也就是 pushState() 和 replaceState() 方法使用时传的第一个参数 state。
4、hash
hash 是 location 对象的属性,它指的是当前 url 的锚,也就是从 # 号开始的部分。修改 location.hash 并监听 window 的 hashchange 事件,也能达到同样的目的。
5、优缺点
SPA 可圈可点,现在已被大家广泛使用,也得到了主流框架的支持,但是它也有局限性,我们将它的优缺点总结如下。
优点:
无刷新体验,用户在切换页面过程中不会频繁被“打断”,因为界面框架都在本地,对用户的响应非常及时,因此提升了用户体验;
分离前后端关注点,前端负责界面显示,后端负责数据存储和计算,各司其职,不会把前后端的逻辑混杂在一起;
减轻服务器压力,服务器只用出数据就可以,不用管展示逻辑和页面合成,吞吐能力会提高几倍;
API 共享,同一套后端程序代码,不用修改就可以用于Web界面、手机、平板等多种客户端;
完全的前端组件化,前端开发不再以页面为单位,更多地采用组件化的思想,代码结构和组织方式更加规范化,便于修改和调整。
缺点:
对 seo 不友好,尽管可以通过 Prerender 预渲染优化等技术解决一部分,但是相对还是不容易索引到它;易出错,需要使用程序管理前进、后退、地址栏等信息;
缺失URL地址,搜索引擎程序无法正确或完整索引整站或页面完整内容。无法分享转发内容对应URL地址等;
6、对比分析
|
单页面应用(SinglePage Web Application,SPA) | 多页面应用(MultiPage Application,MPA) |
---|---|---|
组成 | 一个外壳页面和多个页面片段组成 | 多个完整页面构成 |
资源共用(css,js) | 共用,只需在外壳部分加载 | 不共用,每个页面都需要加载 |
刷新方式 | 页面局部刷新或更改 | 整页刷新 |
url 模式 |
a.com/#/pageone a.com/#/pagetwo |
a.com/pageone.html a.com/pagetwo.html |
用户体验 | 页面片段间的切换快,用户体验良好 | 页面切换加载缓慢,流畅度不够,用户体验比较差 |
转场动画 | 容易实现 | 无法实现 |
数据传递 | 容易 | 依赖 url传参、或者cookie 、localStorage等 |
搜索引擎优化(SEO) | 需要单独方案、实现较为困难、不利于SEO检索 可利用服务器端渲染()优化 | 实现方法简易 |
试用范围 | 高要求的体验度、追求界面流畅的应用 | 适用于追求高度支持搜索引擎的应用 |
开发成本 | 较高,常需借助专业的框架 | 较低 ,但页面重复代码多 |
维护成本 | 相对容易 | 相对复杂 |