前言
页面打开越快,给予用户的体验越好。
有权威的C端app数据规定: 页面打开的速率标准为2s, 因为当页面打开超过2s以后,用户的流失率将会呈现指数级的流失。
实践
日前笔者正在将一个PC的数据列表页重构中,简单介绍下该页面的结构:
页面由 3 大部分构成,
第一部分为数据显示,只负责显示数据,和绑定用户的跳转事件。
第二部分为筛选器,负责页面的数据筛选控制。
第三部分为数据的列表展示,基本也只是显示数据,有tab切换、绑定用户的更改数据、跳转事件。
改造前面临问题(基本把能犯的问题都犯了)
-
第一部分:
1)该部分数据由两个接口的数据共同拼凑而成,该部分UI ready 的时间点是 两部分数据都ready 以后。
所以该部分暴露给用户的时间点 = max(ajax1, ajax2)
2)ajax2 的数据还被第三部分所使用,在切换tab 的时候,因为第三部分依赖于ajax2, 因此又请求了一遍,并再次渲染,
浪费了http 开销,同时拖缓了第三部分的切换速率,还进行了毫无必要的DOM渲染。 -
第二部分:
暂未优化
2.第三部分由于有比较多的数据,因而ajax数据请求的时间非常的长。
1)每次切换tab,都会发送请求。
2)该部分UI也是由两个开销较大的 ajax 的共同构成,大大增加了该部分的渲染速度。
并且ajax2 还依赖于 ajax1 的数据,所以两者是同步。
ajax2在数据非常大的时候,还有很大的几率会由于超时而发生错误。此时这一页面重要的部分就显示不出来了,
对于用户来说是个非常痛苦的体验。
3) 同时更改某一条数据中某一项,页面发生刷新整个页面操作(非常残暴的前端更新机制)
改造后
-
第一部分
1)将UI 按照 ajax 请求来划分,划分为两部分,任一 ajax 完成,UI都可以实现部分的加载
此时该部分暴露给用户的时间点 = min(ajax1, ajax2)
2)缓存ajax2的数据,保证页面对于这个接口只请求一次。 -
第三部分
1)按照tab缓存数据,确保每个tab的请求只会发送一次。
2)将ajax1、ajax2的数据对应的UI部分拆分,ajax2的数据对于页面来说不构成主要的影响,因为当ajax1的数据返回的时候,
这部分的数据就可以先显示出来,减少用户的等待时间。同时如果ajax2的接口发生错误,也不会影响用户的操作。
3)将ajax1 这个非常大的接口,拆分成 三个数据接口:主要数据接口、次要数据1、次要数据2。(这个步骤需要后端配合)
当主要数据接口返回时,即可给到用户反馈。
4)将所有的数据缓存在页面中,更改某个数据的时候,只要更改成功,则更新缓存数据,避免发送请求。
总结
目前笔者用到的页面优化的方法总结起来:
1)模块化:将UI尽量拆解的比较细小,可以使用户尽早地看到页面的一些信息,而非一直在loading , 同时细小的局部对于接口的容错性也可以更好地保证。
2)异步接口、优先显示:页面的开销往往来自HTTP 请求,对于一个UI有很多接口共同组成的,可以优先显示重要的信息,大大减少页面的等待时间。
3)缓存数据:前端保存一份完整的数据,同时维护、更新这份数据,对于用户在页面上操作是十分友好的一件事情。
问题
1)缓存数据:需要注意的是前端缓存数据的能力相对有限,对于一些实时的数据无法做到实时更新,同时缓存数据比较容易出错,后期维护成本会大大增加。