单入口与多入口地址

app的入口是确定的惟一的,只能通过app的主页面一级级进入,这就决定了app没有一些异常进入的途径,从而大大的降低了app产品的复杂度。这样的设定对于流程界面是非常好的,比如从a>b>c这样的流程界面,我们无法绕过app的a页面直接访问到b页面,在产品交互上也不会存在某用户的app的b流程页面被另外一个用户拿到。即使拿到,也是app自定义好的一个可分享的页面。

而h5却是多入口的,h5整个站点所有的h5页面的地址都是用户可感知,可复制地址访问的。因此,对于任何的h5页面都必须考虑除了正常路径访问之外,用户直接访问某页面,应该如何处理的问题。

是否具有宿主优势

所谓宿主就是独立应用所具有的一些特殊能力,这些能力对产品的体验都至关重要,下面通过表格列举了下:

能力 说明
设备网络 可以区分网络情况,针对不同网络给出不同产品方案,并提供网络异常的方案
设备信息 用户的操作系统类型以及版本,地理位置等
设备基本能力 拍照,gps定位,录音
文件操作能力 手机中一些文件的管理,应用文件的一些本地管理
数据存储 完整的应用数据存储方案
稳定的黑盒环境 相比复杂的多种手机端浏览器,宿主的访问环境更为确定,可调试

那么显然会影响的产品体验如下:

对比项 app h5
静态资源 内置在app内,或缓存到本地,免加载 需要加载,依赖于设置浏览器的缓存策略,首次加载无法直接优化
网络加载 性能更佳 依赖于现有的工具网络请求性能
ui渲染 更接近手机系统底层语言,渲染快、体验好,尤其在明显的下拉框、长列表上,体验明显好 依赖于浏览器的内核
环境确定 app的打包环境以及打包之后的使用环境确定,不需要额外的根据app的情况区分,只需要注意系统版本 需要分析宿主浏览器的版本以及内核对ui的影响,当然系统的版本也是有影响的,具体针对不同浏览器都需要影响其打包之后的js以及css文件
数据存储 可以保存需要的用户操作交互数据,能最大程度的降低数据的应用存储 需要借助web存储,并且需要借助一些store的管理工具,目前在复杂的用户数据永存储上没有好的技术方案。

关于页面刷新

对比项 app h5
是否允许直接刷新当前页进入 一般不允许,没有刷新操作 用户操作上允许浏览器菜单上的刷新
刷新时机 从上一个流程状态页面或者访问链路页;页面交互引起的代码刷新 根据链接用浏览器刷新;从上一个流程状态页面或者访问链路页;页面交互引起的刷新
刷新时是否需要做鉴权以及业务判断 不需要,因为正常下是在app的环境里,封闭访问环境 需要对每个页面进行必要的鉴权,并根据业务的状态分析用户是否应该确实访问这个页面还是其他页

所以在app的经典体验是某入口—列表—详情
入口到列表页,数据刷新,列表到详情 ,详情刷新;
但是详情返回到列表,数据以及交互状态保留;列表返回主页面,状态保留。至于如何保留的我后面会详细描述。
在列表页为了让数据有更新同步的部分,一般会提供下拉刷新或顶部双击刷新。

而h5要想做到返回某个页面时具有历史状态,必须借助一些方式:
1.利用浏览器的历史记录,可行但不便利,有些用户交互是不记录在浏览器的历史行为的。
2 利用全局store存储页面的数据以及交互状态,简单的可以,复杂的难,工作量较大,需要区分来源是首次正常加载还是从链路页面返回。
3 利用视觉效果,类似于app内的页面栈,页面层级管理,将新页面展示内容变为模态框全屏覆盖展示,返回时取消模态框显示。简单的1-2级链路可考虑。
4 组件缓存效果,比如vue本身组件支持keep-alive

页面的返回与前进

app返回与前进,在app的头上每个跳转都是到指定app页面。

而h5一般很少按照app的思路去严格设计交互流程,一般返回和前进都是直接定义的历史记录的前进和后退,这在页面上会形成非常多历史页面,非常容易造成页面访问的死循环。(直接每次使用新页面渲染,也会导致体验不好,尤其在目前的spa中,我们跳转页面都是直接页面栈中push新页面)。

在页面返回的返回与前进中,我们需要的一个产品体验的闭环,而不是分割的h5,同样我们也是需要应用的起点页、主页、结果页等的。

鉴权

app集中一次鉴权,一般情况下,app的使用是对登录强要求的,尤其是使用核心业务的页面。除非产品设计了单独的访客模式的应用体验。这样的好处便是,只要进行过一次登录,那么app内的任何页面都是安全的,可以不考虑这个鉴权的问题,并直接使用app内登录的用户数据,因为肯定是登录过的。(另外一点优点便是,app已经登录过的用户名、密码可长期保存在app端,可以直接执行自动登录)

h5却不是这样,一般情况下很多h5页面属于非敏感页面,至少从产品设计角度,觉得这可能不是一个敏感页面,这就决定了我们在开发h5的时候很少会考虑这个页面要不要做鉴权,是不是要某用户才能访问,如果不能访问又该如何?但app内没这个问题,因为如果你的状态不符合,那么你根本不会有进到这个页面的机会。那么如果h5要做鉴权,会做成什么样的?首先如果是短缓存的,我们可以借助会话sessionStorage,在加上store的工具,存储一些信息,然后在h5的该访问入口首先思考是否需要鉴权,如果不需要,直接访问,业务有要求的情况下做业务状态判断;如果需要,那么就做登录授权然后做重定向。我针对h5的部分我做了详细的鉴权逻辑分析。

image.png

app页面栈的优越性

app的页面体验优化页面栈占了很大的部分,可以将不同的页面按照需求不断的层叠堆积到视图层,而上一级页面可以选择不销毁,当不需要的时候,从视图层移除即可。对于一些快速常用的页面,为了提升体验可以直接常用常置到页面中,需要时直接调用传入需要的数据即可。

而h5却没有这样的同时存储多个页面展现的银弹功能,但有几个方向是我们可以进行推敲的。
1 spa可以实现不跳转页面,不重复加载资源
2 异步加载组件,需要的内容异步加载,为页面展现需要
3 常置的模态框组件,需要时,直接模态框+页面组件弹出,可以实现类似app的页面效果,而不是用新的页面打开的方式。比如一个音乐的app,歌曲的播放详情页就是使用的高频页。

同个访问地址的单访问与多访问

app只能在一个环境下访问一个具体页面,这个页面不能同时在app打开两个。

而在浏览器内,我可能会在两个tab页中都打开了同一个h5连接页面,在打开时间不同或者说业务状态不同的情况下,其展示的正确性要校验;并通过刷新,两个tab展示的内容要能实现同步一致。

访问入口的聚合

app具有tab切换面板,具有个人中心,banner等复杂多变的功能入口。

h5一般都是单流程相关页或者就是单页,针对一个应用类型的h5一般很少有人设计访问入口集成页,而这个其实才是刚需。

所以我们能从最近一些超级app中看到h5的微首页的痕迹,在首页里配置主要功能入口,比如支付宝的服务号;微信公众号可以设置应用的主要菜单用于支持主要功能;微信小程序打开界面的展品形态就是内嵌app。

所以像app一样思考h5是必然的趋势,在我们设计的h5超过2个独立访问需求时,就应该考虑h5方面的访问入口的主页地址,并着手上线app,或者小程序类似的产品作为产品矩阵。