购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.2 如何结合技术提升应用的用户体验

接下来笔者基于移动应用的界面设计,向读者介绍如何结合MVC以及各种技术提升产品的用户体验,而这些用户体验可能很难用交互稿的形式表达出来,因为它们大多和性能有关。很多设计师在此之前并不会关注性能的问题,但它确实会影响一个产品的可用性。

3.2.1 从接口的角度构建用户体验

在计算机领域,“接口”在不同场景下都会出现,例如“让后台给我提供一个接口,我直接调用这个接口”“你来设计一个接口,我来实现”分别对应硬件场景、后台场景,以及面向对象的程序设计场景。那么什么是接口?笔者认为接口是提供具体能力的一个标准和抽象。

“让后台给我提供一个接口”,这句话在工程中一般表示的仅仅是提供一项能力供调用方使用,例如后台提供了一项能力,终端可以从后台调用这个接口,查询当前所在位置的天气。这种话在开发过程中用得比较多,常用于前端和后台的联调。“你来设计一个接口,我来实现”,语境一般是在面向对象的程序设计中,对一种能力的抽象和具象分别由不同的开发者实现。例如要实现两种门,一种门使用密码锁,另一种门使用钥匙锁,那么抽象出来的通用接口能力就是开门和关门两个能力,由密码锁和钥匙锁分别实现。显然,它们对开门和关门的实现是不一样的,一种是输入密码,另一种是使用钥匙。负责开门或关门的调用方看到接口后就能明白,可以用钥匙或者密码开门和关门,但并不用关注密码锁和钥匙锁的具体实现,有效隔离了调用者和具体实现过程。

接口象征着提供出来的能力,定义者和实现者一般是不同的,调用者并不需要关注具体细节,只需要关注接口暴露出来的能力就可以了。如果开发人员说,“我需要定义一套接口”,读者应该明白它是在抽象一种能力集,保证调用者只需要知道这个能力并调用,实现者不需要关心谁调用,只需安安心心地做好功能就好了。接口首先保证了大规模程序开发的可行性,通过接口的设计,一个系统被清晰地定义成了多种能力的集合,每一个开发者只需关注自己的模块实现,而调用者负责完成整个程序的业务逻辑。以后如果开发人员说“你给我封装一个接口,我直接调用”,读者应该理解他说的意思是:“我不关心你如何实现这个能力,只要我要用的时候,你给我正确的结果就好了。”

前文所说的接口,英文简称API(Application Programming Interface,应用程序编程接口),API是指一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无须访问源码,或理解内部工作机制的细节。一个API应对应某个特定的方法,提供实现某个特定的功能,同时在请求该API后,返回对应成功或失败的信息。例如阿里大鱼短信平台提供的taobao.open.sms.sendvercode API,其实现的就是发送验证码短信的功能。如果想发送验证码短信,只需要按文档调用该API即可,无须关心该API的源码到底是怎样的,以及实现的逻辑是怎样的。一般而言,API会经过对接平台,厂商可以获取对接平台相关数据信息。

SDK(Software Development Kit,软件开发工具包)一般都是一些开发人员为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件时的开发工具的集合。SDK包含各种API,以及相关的API文档、调用示例等。就像鲁班做一套家具离不开刨子、锤子、斧子等工具一样,开发人员开发应用程序也离不开SDK。在开发场景中,要想在Android平台上开发App,必须从Android官网下载Android SDK,然后利用这套SDK提供的API调用系统能力,例如调用系统屏幕常亮的功能,少了SDK提供的这个工具,开发人员自行实现会非常困难。基于SDK的合作,也就是一方为另一方提供能力和工具集合,一方只负责调用,不用关心其具体实现。

在合作中,常常会面临这样的场景:一个团队不擅长做视频,但项目中又必须加入视频播放场景,而另一个团队是视频领域经验丰富的专业团队,这时二者合作基本都会基于SDK,也就是视频专业团队要为另一个团队做好一个视频SDK。有了这个SDK,只要调用SDK封装的极其简单的“播放”“暂停”接口,就可以完成诸如视频播放的需求场景。在复用场景中,利用已有能力,不去重复创建“轮子”,而将绝大多数“轮子”封装成SDK,供开发者调用,可有效实现生产过程加速。

介绍了这么久,相信读者明白了接口对于开发人员的重要性。对设计师来说,其实除了基本的控件、组件和容器以外,API和SDK也可以当作部件和设计系统的一部分。在设计过程中,如果基于成熟的API和SDK来构建用户体验,那么为我们带来的价值主要有以下两点:第一是减少自身工作量,尤其是交互设计师,很多没必要的交互流程并不需要自己描述,写清楚调用哪个接口即可;第二是便于与开发人员达成共识,减少不必要的沟通成本。如果设计师能证明已有的接口不能满足业务需求,和开发人员解释清楚后,相信开发人员也会愿意修改相关的代码。

笔者建议,读者在日常工作中应该建立自己的接口库,同时多从接口的角度思考用户体验该怎么构建。以应用的注册、登录为例,请问读者能列出几种登录、注册的方案吗?哪种用户体验最佳?相信读者也经常使用输入手机号码和验证码的方式注册、登录账号,那么还有没有比它更佳的体验?有的,那就是使用本机号码一键登录。本机号码一键登录是基于运营商独有网关认证能力推出的账号认证产品,用户只需一键授权,即可实现以本机号码注册或登录,如图3-5所示,在交互流程上完胜前者。在苹果设备上,重新登录账号除了使用手机登录,还可以绑定Face ID实现快速登录,这些都是基于接口带来的便利。

图3-5 京东的一键登录

从接口的角度,也能发现其他应用存在的问题和改进点。以小米手机的MIUI 13为例,笔者发现每次负一屏的快递卡片都会漏了一些快递,仔细看了一下相应的规则,原来小米的快递卡片只能读取菜鸟、顺丰、京东等服务商的快递信息,如果物品是拼多多购买或者快递是其他快递公司负责的,那么小米快递卡片并不会显示,这意味着用户并不能从此处获取完整的信息。但是华为手机总能把所有的快递信息显示出来,这说明华为手机获取快递公司信息的接口比小米手机要完整,所以体验要更好。从另外一个角度来看,如果快递已经到达目的地,那么取件码是不是应该暴露到快递卡片上?对手机厂商来说,其实就是向快递公司多拿一个接口而已,但对用户来说是用户体验的极大提升。

3.2.2 从控件的角度设计用户体验

交互设计师在画交互稿经常会设计点击、长按等交互动作,那么一个控件被点击时会触发哪些事件?从代码的角度来说,如果一个按钮不设置“onClick”属性,以及“onClick”属性没有调用相关函数(一段封装好的代码),那么这个按钮点击后是不会触发任何事件的。这种设置被称为赋予控件一个监听事件,在Android里,点击、长按等交互动作都分别对应一个“onClick”“onLongClick”监听器,每个控件、组件和容器也有相应的监听事件,例如滑动列表有自己的“setOnScrollListener”监听器。从实现的角度来说,开发人员将交互稿转换成代码就是将各种流程变化封装成各种函数,然后监听不同控件、组件和容器上的操作,并调用相关的函数。所以设计师想对交互设计有更深的了解,必须熟悉Android、iOS等平台的开发细节。相关内容请自行搜索iOS的UIControl以及Android的开发者官网关于控件的相关内容。

在过去,由于Android和iOS在监听器以及实现上有所区别,所以两者的设计并不一致,尽管随着时代的发展这些区别已经逐渐消除,但在跨设备交互以及国际化、信息无障碍等新领域上又出现了不一样的定义,这更需要读者多去了解两者的差异才能在做出更好的设计的同时减少相应的工作量。仍是以按钮为例,对比一下Android和iOS平台对于按钮的实现有什么区别。从2022年2月份Android开发者文档上关于“按钮”的内容来看,Android关注按钮的响应点击事件、如何设置监听器以及如何设置按钮的样式,包括无边框按钮以及自定义背景。在iOS开发文档中,按钮的内容除了包含响应事件、外观外,最重要的还包括了是否支持指针事件、国际化和信息无障碍等内容。尽管Android开发文档也有相关的内容,但在规范上仍略输iOS一筹。笔者认为,设计师学习开发文档的好处是可以更好地构建一套设计系统,下面以iOS和Android的开发文档为例解释一下设计系统可以考虑的事项。

(1)控件的展示内容。内容包括文本或者图像,它们在控件中的位置是什么,这时可以从控件内容的水平和垂直对齐方式以及间距来思考。如果展示内容涉及文本内容,设计师应该基于业务需求判断是否需要支持国际化语言,如果需要则应该考虑控件的大小是基于文本长度发生变化还是固定的,同时对齐方式应该根据当地文化进行变化。

(2)控件的状态。以按钮为例,按钮有五种状态来定义它们的外观:默认、突出显示、聚焦、选择和禁用。当按钮添加到界面时最初处于默认状态,这也意味着该按钮已启用并且用户未与其交互。当用户与按钮交互时,其状态会更改为其他值。例如,当用户点击带有标题的按钮时,该按钮将变为突出显示状态。有个细节需要读者注意,基于触控和指针交互的控件状态是有区别的,读者在设计时应该取两者的并集。

(3)输入事件。不同控件有着不同的输入手段,这时需要相应的事件监听器,例如按钮的默认操作事件是点击(Click),如果要增加长按(LongPress)的交互则需要添加长按事件的监听器。以下是Android总结出来的常用输入事件,如果读者感兴趣可以自行搜索“Android输入事件概览”。

● onClick:当用户轻触项目(在触摸模式下),或者使用导航键或轨迹球聚焦于项目,然后按适用的Enter键或按下轨迹球时,系统会调用此方法。

● onLongClick:当用户轻触并按住项目(在触摸模式下)时,或者使用导航键或轨迹球聚焦于项目,然后按住适用的Enter键或按住轨迹球(持续一秒钟)时,系统会调用此方法。

● onFocusChange:当用户使用导航键或轨迹球转到或离开项目时,系统会调用此方法。

● onKey:当用户聚焦于项目并按下或释放设备上的硬件按键时,系统会调用此方法。

● onTouch:当用户执行可视为触摸事件的操作时,包括按下、释放或屏幕上的任何移动手势(在项目边界内),系统会调用此方法。

● onCreateContextMenu:当(因用户持续“长按”而)生成上下文菜单时,系统会调用此方法。

(4)控件的可访问性(Accessibility)。可访问性是为了帮助残障人士更好地使用当前产品,它应该能为用户提供有关其屏幕位置、名称、行为、值和类型的准确且有用的信息。苹果的UIControl已经总结了一套属性,它能帮助盲人或视力低下的用户依靠VoiceOver来使用设备。相关属性如下:

● 标签(Label):一个简短的本地化词或短语,用于标识可访问性元素,但不包括控件或视图的类型。例如,保存按钮的标签是“保存”,而不是“保存按钮”。

● 数值(Value):标签不等同于当前元素的数值。例如滑块的标签定义为Speed,但数值可能是50%。

● 性状(Traits):一个或多个独立特质的组合。每个特质描述元素状态、行为、用途中的某个方面。例如,某个元素表现为键盘按键且当前被选定,这个元素可以使用键盘按键(Keyboard Key)和选中(Selected)的组合特质。

● 提示(Hint):一个简短的本地化短语,用于描述对元素执行操作的结果。提示可帮助用户了解当他们对可访问性元素执行操作时会发生什么,而该结果在可访问性标签上并不明显。例如应用程序允许用户通过在歌曲标题列表中点击其标题来播放歌曲,则列表行的可访问性标签不会告诉用户这一点。为了帮助辅助应用向残障用户提供此信息,列表行的适当提示是“播放歌曲”。

● 框架(Frame):更多是指元素的屏幕坐标和尺寸大小。

以上是控件相关的大概内容,这些内容能帮助读者初步了解跟控件的交互不仅仅只有手势件,其实还有很多属性和状态需要考虑。在内容编写上,笔者采用了iOS和Android混合的方式进行书写,这是因为两者的内容重合度较多但仍有差异,笔者只能摘取通用性最高的内容进行书写,如果读者正在设计不同平台的应用,应该基于该平台获取相关的规范信息。

3.2.3 从设计的角度解决性能问题

关注用户体验的尼尔森诺曼集团在文章 Powers of 10 Time Scales in User Experience 中提到:0.1秒大约是让用户感觉到系统在瞬间做出反应的极限,超过0.1秒的延迟都会被用户发现。当计算机响应用户的输入时间为0.1~1秒时,尽管用户注意到了短暂的延迟,但他们仍然能专注于当前任务;但超过1秒后用户开始变得不耐烦,尤其超过10秒后,用户的平均注意力持续时间达到最大值并开始考虑其他事情。

所以,性能是影响用户体验的一个关键因素,性能不好导致系统不能流畅运行,最终有可能导致用户体验为零。用户对移动应用的性能表现的感知来自多方面,包括启动速度、界面加载时间、动画效果的流畅程度、对交互行为的响应时间、出错状况等,而一个应用的性能同时受到视觉图像、交互方式、代码质量、算法实现以及CPU、GPU、传感器、屏幕尺寸等硬件条件和网络的多重影响。例如为了增强视觉效果,应用必须在迟缓的网速下连接后台服务器以获取更多的资源文件,但由于占用资源过多导致界面渲染的卡顿。

很多产品和设计团队会将性能表现方面的责任丢给技术开发人员;这种传统观念所造成的最直接的结果,就是很多涉及性能方面的潜在问题只有在开发过程才会暴露出来。实际上,设计师的方案会影响总的页面加载时间和感知性能,因此,设计师有义务和开发人员在设计前期共同解决性能问题,这样有助于平衡页面美感和页面速度以提升整个产品的用户体验。

当一个页面出现卡顿的时候,读者会想到有哪些原因和解决方法呢?其实这对于开发人员来说是一个常见但复杂的问题,一般需要通过调试才能知道问题出在哪。身为用户体验的把关人员,设计师也应该有义务去了解问题出现在哪。出现卡顿的常见原因可以分为两种可能性:网络和渲染问题。这很好理解,当客户端向服务器请求内容的次数越多、返回的内容体积越大,客户端下载和处理的时间以及显示在界面上所需的时间就越长。同样,渲染页面所需的独立内容片段越多,界面完全加载所需的时间就越长。

关于网络性能有一句“最快的请求是根本没有发出的请求”的名言,解决网络不佳的方法之一是采用缓存。缓存可以简单理解为将数据保存在客户端,无须向服务端发起请求,一些常用或者最近使用的数据都会通过缓存的方式保存到本地,从而实现“秒开”。现在大多数应都做了缓存处理,包括打开应用时会在开屏页看到几秒的缓存广告,以及大部分应用的首页还有其他依赖网络数据的页面会预留一部分缓存内容,然后开始网络请求进行数据加载。这对用户体验来说是有好处的,用户可以对页面进行操作,等待新数据时可以查看旧数据,更具有“可操作性”与“可用性”,从而减轻了从服务器获取数据这一动作的大小和时间长短;同时使用缓存能让应用在网络不佳、无网络或者服务器崩溃等情况下显得不那么“苍白无力”。笔者认为推特是一个不错的设计案例,如图3-6所示,每次用户进入应用时都会显示上一次浏览的内容,当应用从服务器获取到足够多的资讯数据时,界面顶部会显示一个小浮层告知用户有新的内容可刷新,用户点击小浮层即可跳到界面顶部浏览最新内容。最后,尽管缓存对体验有较多的帮助,但过多的缓存会影响机器性能,所以应用自身应该定期清理缓存,避免造成用户手机内存不足。

图3-6 推特请求最新数据后会在顶部显示一个小浮层,点击则跳到最新数据的位置

网络请求过多导致返回数据较慢,同样可以将一些常用数据作为缓存;也可以将部分网络请求进行合并,CSS Sprites就是很好的例子。很多网站一般会使用大量的小图标,每下载一个图标就意味着一次网络请求,CSS Sprites其实就是把网页中一些图标整合到一张图片文件中,如图3-7所示,再利用CSS(Cascading Style Sheets,层叠样式表)的“background-image”“background-repeat”“background-position”的组合进行图标位置识别,这样就能用一次网络请求把相关图标加载到网页里。对于一些大体积的图像来说,CSS Sprites并不是合适的方式,这时可以使用Base64编码器将图像转换为等价的文本编码,然后将编码嵌入页面中,这样可以节省每一张图片的HTTP请求,进而提升加载性能。

图3-7 将需要的图标整合到一张图片文件中

还有一种降低网络请求的方法是采用懒加载(Lazy Loading)模式,它也被称为延迟加载,这种方法一般用于加载很多图片、视频的列表页面。懒加载在网页中的具体操作可以理解为:相关图片在没进入浏览器可视区域前并不会从服务器获取资源,它只会将页面上图片的src属性设为占位图片的路径,而图片的真实路径则设置在data-original属性中,当页面滚动的时候需要去监听Scroll事件,在Scroll事件的回调中,判断懒加载的图片是否进入可视区域,如果图片在可视区域内将图片的src属性设置为data-original的值,这样浏览器会开始从服务器获取图片资源。

懒加载的好处除了提升用户体验,还能减少无效资源的加载,并且防止并发加载的资源过多阻塞js文件的加载。但是做好懒加载的极致体验需要设计师考虑以下因素:

(1)当懒加载的图片进入可视区域时才获取图片的真实路径并重新加载数据其实已经过晚,这样用户需要等待一小段时间才能看到图片,所以懒加载应该配合预加载技术进行数据加载。预加载的意思是预先告知浏览器某些资源可能在将来会被使用到,然后将所需资源提前请求加载到本地,这样后面在需要用到时就直接从缓存调取资源。懒加载和预加载的结合依赖于Scroll事件的判断,即判断图片在什么时候即将进入浏览器界面被用户浏览。最好的方法是结合用户的浏览内容速度和滚动屏幕速度进行预判,如果做不到上述这一点,交互设计师可以预设一个值,例如,图片内容离浏览器可视区域1.5个浏览器高度时进行预加载。

(2)上文提到懒加载会将页面上图片的src属性设为占位图片的路径,这有可能导致界面排版出现问题,原因在于占位图片和原图大小比例不一样,导致原图加载后当前界面排版发生变化。要解决该问题只有让占位图片和原图宽高一致,要么提前获取图片宽高大小并告知占位图片设置一样的数值,要么让所有图片先展示缩略图,然后让缩略图和占位图片裁剪成同一比例,后者被应用在大多数应用中。

相信读者偶尔也会遇到应用久久刷不出来数据的情况,这有可能是用户发起网络请求过多导致的服务器崩溃,或者是用户所在地理位置的影响。由于客户端请求和接收信息都是通过物理网络进行的,而内容进行长距离传输的速度是有极限的,所以用户的设备距离服务器越远,通信所需的时间也就越长。举个例子,当一名中国用户访问在美国的服务器,所需的时间会比美国本土用户要久一点。

遇到这种问题更多是开发人员通过技术手段去解决,例如,增加服务器和网络带宽,尽管设计师在此无能为力,但也可以了解CDN(Content Delivery Network,内容分发网络)这个技术细节。CDN可以简单理解为应用的内容和数据已经部署在各地的边缘服务器上,使得当地用户就近获取所需内容,从而降低网络拥塞并提高用户访问响应速度。CDN对于社交或者视频应用来说尤其重要,例如,用户发送微信消息对方瞬间收到也是采用了CDN服务;用户观看抖音视频时为什么能流畅地往上滑动观看下一个视频,因为抖音也采用了CDN服务和预加载技术。

对于一些体积较大的高清图片来说,预加载和缩略图占位是常用的技术手段,但是如果客户端需要加载大量图片,仅靠以上手段并不够用,这时候需要在服务器提前压缩图片以便减少资源体积和减少用户的等待时间。以往会将图片从PNG格式转换成JPEG格式,但是JPEG格式容易引起图片失真,同时也让图片失去Alpha通道,即原图透明区域会变成白色。在此,笔者建议读者可以将原图格式转换为WebP格式。WebP是一种支持有损压缩和无损压缩的图片文件格式,根据Google的测试,无损压缩后的WebP比PNG文件少了26%的体积,有损压缩后的WebP图片相比于等效质量指标的JPEG图片减少了25%~34%的体积。同时WebP具备动画播放能力,在图像质量、控制体积大小上都优于GIF格式,因此也可以取代GIF动画。目前WebP格式已经被广泛应用于各大最新版本的主流浏览器和iOS、Android操作系统,读者不用担心WebP兼容性问题。

讲完网络问题,接下来开始关注渲染问题。在网站设计中,当用户开始加载页面时,首先出现的是空白页面。空白网页是一种很糟糕的用户体验,移动应用也是如此,而这个用户体验问题可以通过优化加载顺序来解决。以Boss直聘的Android客户端为例,对于正在求职的用户来说经常打开应用查看HR或者猎头的回复消息是常态,但他们打开应用发现没有消息会立即关掉应用,因为他们担心会被周围的其他同事发现。为了解决这个问题,当Boss直聘首页还没刷新完最新内容时,底部的Tab已经显示了有几条内容未读,这有效解决了用户只需瞄一眼就能获取关键信息的需求。因此,读者在设计界面时可以基于信息的优先级跟开发人员沟通清楚哪些信息是需要优先加载的。

根据设备特点动态调整请求内容的大小除了能提升网络性能,在一定程度上也能提升渲染性能。以加载视频为例,当一个分辨率为720P的设备全屏加载一个4K视频时,系统需要将分辨率等比例压缩成720P,如果设备的Soc本身就差,此时播放视频会出现卡顿,而且被压缩后的视频显示效果可能会更差,所以视频应用一般会根据设备的性能动态调整视频可提供分辨率的选项。图片的加载也是如此,不过图片的加载有自己的特点,那就是基于渐进式的JPEG文件在加载时以低清晰度形式马上显示出来,然后逐渐变得更加清晰。渐进式JPEG显得比基线JPEG加载得更快,因为它会用低清晰度的图片一次性填充所需的全部空间,而不是从上往下一块一块地加载,所以在一定程度上也能有效提升用户体验。

相信读者都听说过“黄油般”顺畅这种说法,其实这是指界面在滑动时能稳定在60帧左右,如果帧率过低则被认为发生卡顿。出现这种现象是因为界面的内容改变导致设备重新绘制界面,包括界面某个元素的视觉属性(例如背景、颜色、边框半径、阴影)的改变,或者显示、隐藏某些内容都会导致当前界面重新绘制,这也就是为什么游戏、动画效果(例如位移、缩放、旋转和透明度等)以及基于Canvas的界面容易引起卡顿。读者在设计网页或者Android应用时,可以分别打开Chrome的开发者工具的“Performance”或者Android开发者模式下的“FPS显示”显示实时的帧率变化,在设计iOS应用时只能让开发人员通过调用CADisplayLink的方式实现对帧率的实时监测。

由于Android手机的性能问题较多,所以在这里笔者着重讲解一下怎样发现并解决相关的问题。首先,笔者介绍一下Android自带的“调试GPU过度绘制”,它能对界面进行彩色编码来帮助开发者识别过度绘制。开启后如图3-8右侧所示,它能显示出应用可能在何处执行不必要的渲染工作,这可能是GPU多此一举地渲染用户不可见的像素所导致的性能问题。相关的彩色编码如下:显示原来的颜色代表没有过度绘制,蓝色代表过度绘制1次,绿色代表过度绘制2次,粉色代表过度绘制3次,红色代表过度绘制4次或更多。

图3-8 普通模式和打开“调试GPU过度绘制”的界面

关于如何解决过度绘制的问题,Google也给出了相应的策略来减少甚至消除过度绘制,它们分别是移除布局中不需要的背景、降低透明度和使视图层次结构扁平化,感兴趣的读者可以自行查阅相关内容。在这里笔者要强调一下“使视图层次结构扁平化”。由于开发人员拿到设计稿后会根据自己的理解去对视觉界面进行视图上的重组,其间有可能嵌套了若干个层次结构,结构越多,对应用性能产生的影响越显著。读者可以通过Android开发者模式下的“布局查看器”查看开发人员设计的布局,它在一定程度上反映了视图层次,当读者发现不合理的地方时应及时和开发人员沟通。

除了Android,iOS和Web也有相应的工具可以帮助开发人员了解当前的渲染情况和存在的问题,但iOS相关工具使用起来比较麻烦,笔者建议读者多和开发人员交流。关于Web的相关工具可以直接打开浏览器的开发者工具查看,Network、Performance等标签页都能帮助读者更好地了解当前网页加载状况,从而优化整体的性能。最后做个总结,设计师做设计时应该考虑到自己做的设计是否会对性能产生影响,以及主动留意当前性能对用户体验的影响,这样才能保证自己设计的用户体验处于一个良好的状态。

3.2.4 如何看待应用的启动和状态恢复

读者有没有想过为什么大部分应用在启动时都会显示一个开屏页(也被称为启动页)?从品牌和推广的角度来看,开屏页除了承载大大的logo,还能给设计师足够的空间将自己的创意和设计理念体现出来,如图3-9所示。对于一些有变现压力的商业团队来说,开屏页是最棒的变现位置,因为用户每次启动都要经过这个页面,所以能看到有些应用会将开屏页设计成一个个广告的展现页面,有些时候一个广告长达十几秒,然后在界面的不明显区域显示“跳过”按钮,允许用户跳过广告直接进入应用主页。

图3-9 不同应用的开屏页

对于用户来说,真的会对开屏页的内容感兴趣吗?用户只想快点进入应用寻找自己感兴趣的内容。那为什么应用需要一个开屏页?原因是开屏页可以充当“遮羞布”。应用刚启动时客户端会执行各种任务,包括创建线程、拉取UI资源绘制屏幕以及向服务器发起多次网络请求来获取最新内容,尤其是2010—2016年网速较慢的2G/3G年代更是如此。在Android 12以前,由于Android代码设计的问题,应用启动时如果不做任何处理,用户第一眼看到的一定是一个空白页面。在启动过程中还要考虑到内存不足导致性能卡顿的问题,而开屏页的存在及时隐藏了这些问题。以上问题对于性能较好的手机以及现有的4/5G网络速度来说,合理的网络请求优化和内容加载在1~2秒内即可完成,但是国内绝大部分应用会在开屏页增加5~10秒的开屏广告,所以开屏页也成了用户吐槽对象之一。

在开屏页发起的网络请求主要从不同服务器获取相关数据,以社交应用为例,这时应用发起的网络请求包括对用户个人信息的验证(尤其用户在另外一台设备重新设置了新密码)、最新的聊天内容、新的好友请求、朋友更新了几条动态以及应用版本更新。如果应用启动时把所有的数据都获取,那么用户会明显感受到卡顿的同时对于应用的服务器来说也会带来更大的压力,所以读者在考虑开屏页的数据获取时应该根据业务的实际情况按需获取,例如哪些数据是必须验证或者要在首页显示的,其余数据可以在用户交互过程中实时更新。

所有的业务数据放在同一服务器一次性下发给用户会存在两个问题。第一个问题是当大量用户同一时间打开应用获取数据时有可能导致服务器崩溃,而且服务器万一真的崩溃了那么所有业务都无法使用,就跟全部鸡蛋放在一个篮子里一样,篮子掉了鸡蛋都会破碎;第二个问题是服务器的带宽有限,如果大量用户同一时间拉取数据会导致每位用户加载数据的时间加长,所以有些应用都会将不同业务的数据放置在多个服务器上。

既然如此,应用可以串行或者并行的形式从不同服务器获取数据,在节省时间上来看是后者占优。在计算机中有“多核”和“多线程”的概念,两者结合在一起可以让计算机同时工作多个任务。上文提到的串行是指一个请求完了之后再进行下一个请求,假设上文提到的社交应用每个请求各需要1秒,那么获取完所有数据需要5秒的时间。并行是指多个请求同时进行,如果将上述请求通过并行的方式,那么时间能不能压缩至1秒?不能,因为最新的聊天内容、新的好友请求和朋友更新了几条动态的数据出于安全的需要,应该要等用户个人信息验证完才能获取,所以通过并行的方式获取完所有数据的时间可以压缩至2秒。

如果把网络请求看成控制器的一部分,那么通过控制器的设计优化了应用的加载时间,这对用户体验的优化有着重大的帮助。读者看到这里,应该知道这个细节并不会出现在交互稿和UI稿上,但它确实能影响整个用户体验。如果读者在后续设计中存在优化时间的诉求,可以考虑采用计算机多线程并行工作的方式,但要切记一点,每个应用都有一个线程池,能开的线程数量是有限的,同时每开一个线程应用需要的资源开销也会额外增加一点,所以线程不是开得越多越好,读者应该和开发人员做好相应的沟通。

以上的启动方式在行业中被称为“冷启动”,还有另外两种启动被称为“热启动”和“温启动”。热启动是指应用在后台时被用户重新带回到前台,在后台中应用的当前视图和数据仍保存在内存中,那么系统可以顺利地将应用调回到前台。但是,如果系统因为内存不足把应用的部分或者全部资源释放掉,那么用户从任务管理器调起应用时,应用需要重新加载。如果开发人员不做任何的操作,那么应用会从冷启动的方式重新进入主页,如果开发人员了解“温启动”,那么应用是有可能回到之前停留过的界面。这种“温启动”的方式在iOS和Android中都有相关的技术可以实现,如果读者感兴趣可以到iOS Developer或Android Developer分别搜索“NSUserActivity”和“保存界面状态”。

应用的状态恢复在跨设备交互或者大屏设备交互中变得异常重要,因为用户有可能同时处理多个任务,这涉及App之间的切换,以及使用“侧拉”或“分屏浏览”实现App的组合使用,甚至为同一个应用创建多个窗口。例如在不同的“分屏浏览”中打开了四个笔记,当用户再回到某个笔记时,它们都应该能够从中断的地方继续,而不是重新进入主界面。应用状态的恢复是实现以上体验的核心部分,读者一定要和开发人员沟通清楚相关需求,这样产品才能更好地服务于跨设备交互。通过技术提升用户体验的关注点还有很多,在这里笔者不再一一阐述,感兴趣的读者可以多和开发人员交流。 n234hXGpdEm/gV3LcyKzYawRz4qK+1YhpQcSsm//IEwvJp7IAM+6k2dGr5eiaSiH

点击中间区域
呼出菜单
上一章
目录
下一章
×