前端的挑战-----单页开发的体验

什么是单页应用
所谓单页应用,指的是在一个页面上集成多种功能,甚至整个系统就只有一个页面(一个html),所有的业务功能都是它的子模块,通过特定的方式挂接到主界面上。

为什么会有单页应用
我们知道ajax技术的产生,一部分原因就是为了让访问网页的用户在不刷新页面的情况下,在页面上查看数据的变更。我们可以说ajax提升了体验。

随着互联网的发展,浏览器端承载的业务愈发复杂,web前端早已不再是一个简单页面,ajax局部刷一刷的小玩意。动辄数十个子页面的应用市面上随处可见。而这些子页面享有许多共用的资源(静态、动态),加载它们需要不少的时间,要想不重复加载这些资源,有一个显而易见的办法 —— 把他们放到一个html中。

所以说它是ajax技术的进一步升华,把ajax的无刷新机制发挥到极致,因此能造就与桌面程序媲美的流畅用户体验。

单页应用带来的困扰
我们知道,把十几个二十几个子页面的程序,放在一个html里面,不是cut+paste就能搞定的。原本不相关的程序,放在一起的结果,就是程序世界的质能方程 Errors = (More Code)^2

##单页应用的体验
言归正传,如何尽可能增强单页应用的操作体验?

那我们先来看一下,对于用户来说,影响体验的,包括哪些

1. 页面初始的加载速度
2. 交互的响应
3. 页面数据的正确性(尤其是网络异常状况下)

--
前两点其实很多文章谈的都比较多了,这里我尽量一笔带过,重点谈一谈第三点。

页面初始加载速度
- 静态资源的按需加载 (良好的模块化前提下,使用webpack、 systemjs这类module bundler工具)
- 动态资源的按需获取 (需要前端数据层的良好架构)
- 服务端渲染 (把页面加载过程中,前端“获取”数据,并“生成”页面的过程,放在服务端完成。不适用于首屏过于复杂的应用)

交互的响应
- 速度:后端请求回来的数据,前端缓存,后续同步。避免同样的数据重复请求。
- 异常处理:现今移动办公普及,如何在网络状况欠佳时,在ui上给用户良好的等待或者提示,也不可小视

####页面数据的正确性
这个是我比较想谈的,也是我们在实践过程中遇到过很多问题,也尝试过一些解决方案的。

我个人觉得,对于这件事,想要做好,就这几个字: **“良好的缓存管理”**,这里的缓存,指的是前端缓存的模型。

别看就这几个字,做起来相当有难度。为何?

先说内存的来源,有以下几种:

- 浏览器缓存(indexDB,localStorage之流)
- http请求
- webSocket推送

不同的来源,影响同一份数据,需要良好的抽象,让业务层屏蔽对数据来源的感知,现有的被广泛应用的解决此问题的库有RxJs, CycleJS等,早先也有人提出MVI的概念,皆为此生。

再说内存的变更

正常状态的变更,无需赘言,这里只说几类异常状态。

http请求失败

这里需要提到一个词,叫**“操作补偿”**

什么是操作补偿呢?

从逻辑上来讲,当我们在界面上操作,创建一条任务的时候,新的这条任务不应当立刻显示出来,而是应当等到服务端确认成功了,才加到界面上。但很可能我们的网络不好,这一步用户要等很久。从用户体验的角度,这样是不好的,所以我们可以先把界面放上去,然后等创建成功的消息回来之后,再把一些唯一标识之类的东西回填到内存数据中。

单步的操作补偿还算是不太难,如果有多步的话,就非常麻烦了,举个极端情况的例子来说,用户新增了一条任务,服务端还没返回的时候,他就立刻在这条任务下创建子任务,但子任务这时候没有父任务的id,如果想给这步也做操作补偿,就比较麻烦了。甚至说,连续进行了几步操作之后,发现之前的操作失败了,后续处理会非常复杂。

我们的产品一样遇到这个问题。我们的做法是 —— **“折中”**,对于重要数据,做单步补偿,或者两步补偿。如果遇到前端模型从属关系复杂且上级模型的写操作失败,抑或是过多步的补偿,就提早通知用户,并在ui上锁死用户的交互入口,避免后续写操作的发生。

这里如果继续再做也是有的做,和离线应用思路相似,把操作的结果记录在客户端本地,等到网络正常,再和后台进行数据同步。


断线重连

网络抖动、网络的切换、电脑休眠再打开等等,导致我们需要面对更复杂的网络状况,那当用户再次联网的时候,应用需要去重新链接。

这时,一个理想的单页应用,会在重新连接的时候,把之前所有发生的事件产生的最终结果,也就是最新的状态,同步回来。

我们的应用是有协作业务的,同一企业的用户间,享有同样的模型,通过webSocket进行同步,保证模型的即时性和正确性。所以这也是我们遇到的一大挑战。我们解决的方式是webSocket的重发。

热更新

前面提到,用户有可能长期开着我们的应用,然后中间一直没有刷新。正常情况下,业务变更都应当会被全部推送过来,界面所反馈的状况始终是最新的,符合现状的。但我们需要考虑到另外一个问题,系统升级怎么办?

我们当然可以推送一个通知:本系统已经升级了,请点击刷新。但能不能做得更好?这是有可能的,要达到这种目的,就要使用热更新这种手段,把代码的模块化和变更管理都做到极致,每次更新的代码模块也推送过来,并且作为补丁应用到当前系统上。这种机制对开发团队的水准要求很高。

最后
曾经听过一个说法,如何判断一个单页面产品的技术水准呢?
连续开几天不关,不需要刷新页面,应用一样可以正常、正确、流畅的使用。

这里面的含义,相信做过单页应用的同学们心里都懂。

小结

说了不少,总结一下。我们提到了一些问题和针对问题的能够提升单页应用体验的方式,如果实现出来,肯定是可以让使用者非常开心的,但需要冷静权衡理想与现实之间的差距。我们做的是软件工程,必须适当放弃美学,将有限的人力精力投入到要害所在。

posted @ 2017-10-13 15:49  数据观  阅读(417)  评论(0编辑  收藏  举报