时间:2017-05-16 来源:互联网 浏览量:
导读
自2015年Office移动版推出以来,超过2亿下载。其功能集之丰富接近PC版,却能流畅运行于低配手机、平板上,这无异于让“大象”跳舞。到底是怎样让Office这头功能巨大的“大象”在移动设备上轻快流畅地跳起舞来的?这有赖于微软的“性能开发周期”流程。
(全文共6451字 预计阅读时长:6分钟)
一、案例背景
2015年全新推出的微软Office移动版,如图1所示,重写了代码,以适应触控、小屏幕、移动、云端、协作等需求。移动版包括Word、Excel、Powerpoint、OneNote等应用,支持Android、iOS、Windows三大平台上的手机和平板设备。
Office移动版推出以来,超过2亿下载,Android/ iOS/ Windows商店评分均超过Google Docs,iWork等主要竞争产品。它的功能集之丰富接近PC版,却能流畅运行于低配手机、平板上,这无异于让“大象”跳舞。例如,我们主打的一款低价手机Lumia 635内存大小仅为512MB;Word/Excel/Powerpoint三个Windows Phone应用安装后的文件占硬盘大小仅110MB。
我们是怎样让Office这头功能巨大的“大象”在移动设备上轻快流畅地跳起舞来的?这有赖于我们的“性能开发周期”流程。本文将代表个人观点为读者分享这一流程。关于性能编程技术,请读者参考MSDN文档:Performance(Windows Store Apps)。
图1 Office移动版
二、问题提出
●2.1 性能是什么
性能包括两方面:一个是速度要快,一个是资源要省。可以总结为:“又要马儿跑得快,又要马儿不吃草”。性能在桌面软件、移动应用、网页应用和后端等不同领域的含义有所不同。表1所示列举了一些典型含义。
表1 性能的含义举例
● 2.2 性能有多重要
我称性能为“看不见的关键体验”。在我看来,性能是软件的竞争利器。iOS在很多方面比Android操作系统更受用户青睐,其原因之一是iOS感觉更流畅,虽然iPhone 4S只有512MB内存,但是用户感受比一些1GB内存的Android手机还快。又比如微信在很多类似产品中脱颖而出,其原因之一是微信发消息、语音、图片时感觉太快了。
研究表明(App Attention Span Study 2014),“近90%受访者会因为App性能差而卸载;性能是造成App和网页用户沮丧的头号原因;65%的人对App性能的要求越来越高;约1/3移动银行App用户会因为App性能不好而换银行;如果一个产品或服务的App性能比竞争产品好,29%的人宁愿多付钱选择它。”可以说,性能者,“死生之地,存亡之道,不可不察也。”
三、解决思路
为了确保产品的性能,有必要用流程来保证。性能开发周期如图2所示。在软件开发流程的每一步,嵌入相关性能环节。注意这个流程在几天发布一次的快速迭代开发中也是适用的,因为每一步的性能工作可以做大也可以做小,重要的是在原则上有这些环节。
一旦功能需求确定,就应确定性能目标。
在系统设计之前就要确立性能目标,是因为性能目标有可能影响到系统如何架构。
系统设计之后就要做性能风险分析,因为很多性能风险是由系统设计带来的或决定的。
在写代码之前就需要做性能风险分析,因为对性能风险的解决方案有可能影响到如何写代码。
写功能代码之后要写相关的性能日志,这样测试时可以同时进行性能测试。
在发布后不仅要运营用户增长,还要同时运营用户性能体验,两者关联起来有助于我们看到性能对增长的影响。
图2 性能开发周期
接下来,我将对性能周期里的每一环节详细阐述,最后再探讨一下怎样建设一个性能团队的途径和方法。
四、案例复现
● 4.1确立性能目标
确立性能目标的一般流程如图3所示。首先从功能需求出发,确定关键场景,再从关键场景中抽取几个比较重要的关键指标,最后对这些指标确定性能目标值。
关键场景是功能需求中用户最常用,体验最重要,最体现产品价值的那几个场景式功能。关键指标在上一节性能的含义中有所举例。目标值的确定比较有讲究,它来自用户期待,产品的目标永远是“超出用户期待”。而用户期待来自以下多个渠道:
用户在产品评论中的性能反馈和要求;
竞品的类似功能的性能;
用户设备统计值,比如大部分用户来自1GB内存的Android手机;
要和公司产品线上姊妹产品当前的性能值保持相当;
不能比产品上一版差。
图3 确立性能目标
举个例子,对Word移动版,一个关键场景是Word应用的启动;其中一个关键指标是Word启动到响应用户交互的时间;它的目标值为1秒。
注意:目标值对自动化测试和用户数据有不同含义。对自动化测试,我们可以确定一个或几个典型参考设备和环境,比如iPhone 4s,要求在实验室这个参考设备上启动时间永远不能超过1秒;
而对于真实用户,他们的设备和环境参差不齐,同样是iPhone 4s,却可能因为系统上装了其他软件或移动网络条件不同而产生不同的启动时间,所以对用户数据的目标一般使用统计分布值,比如要求90%的用户启动时间都不能超过1秒。
性能目标一旦确定,应被写入功能需求作为产品的成功条件之一。作为“长期靶心”,不应该轻易改变。
● 4.2分析性能风险
一旦系统设计确定,就要在写代码之前进行性能风险分析,因为对风险的解决方案有可能影响到如何写代码。分析从系统设计出发,头脑风暴可能的性能逆境,穷举可能的对响应时间和系统资源的性能威胁,也就是不达标的风险。对每种风险,研究缓解方案和对策。
比如,系统设计是在Word启动时执行跨网络的任务,而一个可能的逆境是网络条件差,导致的风险是Word启动响应时间有可能超过1秒的目标值。对此研究方案对策,最后的解决方案是推迟相关的网络任务到启动响应之后。如图4所示。
图4 分析性能风险
方案对策有三个不同的战略级别:
最有效的是优化架构设计,包括精简加载模块,重组文件,UI/工作消息调度,闲时处理任务,按需启动/下载/升级……等。这项工作直接导致系统设计的修改,这也是为什么不能把风险分析推迟到写代码阶段的原因。
其次是根据硬件和环境而进行功能的缩放,硬件包括用户设备的CPU、内存、分辨率、硬盘大小、电池电量,等等;环境包括网络延时、网络带宽、网络套餐,等等;根据动态测量设备和环境,功能的缩放包括关闭动画、多分辨率图片图标、精简加载的资源,等等。
最低一级是优化代码,包括编译/链接优化、按配置优化(Profile-Guided Optimization)、二进制符号分析、重复源码分析,等等。
●4.3 写性能日志
性能日志就像printf(见图5),乍一看没有太多要注意的,但是好的printf其实学问很深,对debug及其重要。
性能日志要记录哪些内容呢?
时间:这样能通过收集的开始-结束时间的差值得知一个场景所花时间是否超过性能目标值,也能通过时间找到这一时间其他的相关日志,进行综合分析。
资源:记录内存,网络,读写等资源的开销。
关联:关联当前代码行和别处的有关代码。有几类关联,第一类是记录调用关系,哪个方法call了我,我又call了谁;第二类是跨线程异步关联,哪个线程call了我,我又在等待哪个线程完成;第三类是跨客户-服务器关联,我是哪个设备,而服务器在哪个数据中心。
注意:日志要反映真实用户的体验。比如响应时间要在UI真正空闲下来可以响应用户输入之后才算结束,否则到时候收集上来的数据显示响应很快,但用户那边真实的体验却很慢,这就是自己骗自己了。
另外要注意的是性能日志的性能本身,这听起来比较讽刺。要测量日志本身消耗了多少CPU,内存,读写,网络使用资源。日志应该本着“少而足够”的原则。日志应该是能够分级输出的,比如是内测还是发布时输出,是今后一直输出还是就当前版本输出,等等,应用有开关统一控制。日志还要能分离元数据,不需要在每条日志里都交代这是什么用户设备,是哪个应用版本,是哪个用户对话;而应该对每个用户设备只记录一次设备信息,对每个应用只记录一次应用版本,对每次对话只记录一次对话上下文,而这次对话里发生的十条日志都只需要有个关联ID,能让我通过JOIN找到对话、应用、设备的元数据就行。
最后,日志越少不仅消耗资源越少,而且debug时噪声越少,看日志越干净,越高效。输出用户日志时要请隐私法律方面的专家进行隐私评审,避免输出能定位到具体某个用户的隐私信息,缠上不必要的法律纠纷。
图5 写性能日志
● 4.4自动化性能测试
产品加入新功能常常伴随着更多的时间开销和系统资源开销,而我们要想知道产品的新版本是否仍然能满足性能目标,最简单的方法是在可重复、可控制的实验室环境下,用固定参考设备测试几个关键场景的性能。
当新代码加入时,要判断代码的性质是否有可能影响性能,如果是则开启自动化性能测试。自动化性能测试的流程如图6所示。例如,新代码是在Word的启动路径上,从而有可能影响性能。部署的机器包括手机和平板设备,相关的场景包括Word的冷启动和热启动。收集的日志统计了启动的耗时、内存、CPU、读写等指标。对比结果发现,耗时比上一版有明显的倒退,并且根据事件日志分析定位到了一行网络调用代码。从而生成bug和报表,交给开发人员。
开发人员应该能一键打开相关分析界面,包括相关代码的历史版本对照,可视化性能分析工具,等等,从而高效地理解问题并修改代码。要把性能倒退的bug放在高优先级,才能不让性能日渐流失,成为功能的牺牲品。
图6 自动化性能测试
●4.5 性能运营
自动化性能测试能够在实验室纯净的设备环境中可重复、可控制地测试几个关键场景的性能,为上线把关,然而不能得知世界上千差万别的设备环境上真实用户的体验。因此,需要在上线后做用户性能运营。
性能运营的流程
性能运营的流程如图7所示。
用户使用产品时在他们的设备上生成性能日志。在正式发布之前首先进行内部上线,由企业内部员工内测使用,生成的日志更少隐私限制,能提供原始丰富的debug信息,能在发布之前及时解决问题,所以内测非常重要。
无论内部或外部的用户生成的日志,在他们的设备上根据产品里指定的收集规则来收集日志,得到用户真实体验到的时间,资源使用等性能指标,并上传到公司的数据中心。收集到的指标和性能目标比较,达不到性能目标则说明出了问题。前面提到写性能日志时要注意日志的性能和隐私问题,这里在收集、上传、更新收集规则时也要注意性能问题,可以对条件、频率和采样率进行限制。比如,每隔1分钟收集一次日志,只有Word空闲时才能每隔十分钟上传1次日志,每隔1天检查收集规则,采样率是只收集千分之一的用户,以保证大部分用户不受收集上传的影响。
数据中心根据上传的性能结果生成报表,由运营人员监控。
报表的内容分三个层次:
第一是产品的性能有没有问题(Whether);
第二是当确定“有问题”的时候定位问题的影响范围,比如发生时间、地区、相关设备类型,等等,也就是“问题的上下文(Where/ When/ Who/ Which)”;
第三是运营人员把确定了的问题交给开发人员进行技术诊断,也就是“为什么会有问题(Why)”。
开发人员收到问题的上下文后,根据需要进一步要求收集在这个上下文里更多的用户细节数据,比如Call stack,从而找到bug,改善代码。
图7 性能运营
性能运营举例
这里对报表举两个例子。
第一个例子是用户性能日志的报表。
首先,运营查看“用户启动耗时直方图”。假设既定性能目标是80%用户要在1秒内启动,而报表结果显示80%的用户启动时间超过了1.5秒,则说明有了问题。接下来运营查看“内存大小和启动时间”散点图,发现在启动超过1秒的用户主要是内存1GB的手机用户。这说明内存使用需要优化。
散点图上显示的是启动时间的中位数,实际上我们可以画多个分位数来刻画分布曲线,比如50%、75%、90%、95%。同样地,运营查看国家/地区、日期/版本号等上下文数据和启动时间之间的相关性,从而确定问题的范围和性质,交给开发人员。开发人员通过要求收集更详细的日志,得到代码每一部分影响到的启动秒数,从而发现瓶颈代码,尝试进行优化。
第二个例子是用户在应用商店等渠道对产品性能文字反馈的报表。
首先,客服或运营收集并挖掘用户的文字反馈信息,如图8所示,得到性能差评占所有评价的百分比随时间或版本变化的曲线,当发现新版本导致更多性能差评时,则说明性能有了问题。接下来运营查看差评里具体的热门话题榜,发现收集信息慢是抱怨最多的一项。
经过一系列定位问题的范围,运营交给开发人员去诊断收集信息慢的原因。开发人员找到和差评相关联的客户端以及服务器端的详细信息,从而定位相关的代码并尝试进行优化。
图8 用户对产品性能文字反馈的报表
这里小结一下实验室自动化测试,用户日志监控以及用户文字反馈这三种不同的性能衡量手段,如图9所示。本地测试在发现问题的及时性,信息的深度和可行动性方面最好,但离用户真实体验较远,也不能发现未知问题。
监控用户文字反馈能够近距离了解用户的感受和需求,发现未知问题的能力很强,但有些问题等到此时发现已经得罪了用户,而且得到的信息可能不足以帮助定位出问题的代码。用户日志监控的效果介于测试和反馈之间,弥补了两者各自的不足。要想有效地衡量用户性能体验,三者缺一不可。
图9 自动化测试,用户日志监控和用户反馈监控的比较
● 4.6性能开发周期小结
性能开发周期的好处有如下3点。
避免了性能问题导致用户体验致命缺陷,产品失败/落后竞品;
避免了开发后期由于性能问题而不得不重改架构,浪费巨大;
避免了不清楚真实用户性能体验,能更好地帮助商业决策。
因此,可以说,性能是用户体验的关键,需要用流程来保证。因而有了如下的性能开发周期。
团队和产品线总体从一开始就有量化的用户体验目标和系统资源用量预算。
架构师和开发人员能及早发现系统设计中的性能瓶颈问题,提前修改设计。
随着开发深入,性能测试防止新的功能不以牺牲性能目标为代价。
用户性能运营使得运营人员和开发人员高效合作,解决用户性能问题。
● 4.7怎样建设一个性能团队
我通过在Office性能团队的工作,关于如何建设一个性能团队有些心得。一个性能团队的人员组成,每个人员负责的方方面面,以及他们和功能团队之间的工作关系,可以用图10所示来表示。
图10 如何建设一个性能团队示意图
五、 案例启示
Office性能团队的价值在于:
帮助功能团队掌握了技能,预除了隐患,倒逼了设计;
帮助Office有效地、系统化地、稳定地改进性能。
那么我们做了哪些对的事呢?
从开发早期就渗透,贯穿了产品全周期。
了解产品功能和程序架构,从而深入地进行性能分析和debug。
了解功能团队桌前行为,从而提供了贴心工具服务。
不间断警觉地监测,从而使性能天天向上。
信念:性能是关键体验,竞争利器!感染了功能团队。
早期就得到了高层的“尚方宝剑”:功能团队的合作承诺。
另外,我们对Office功能团队也带来了影响。几年以前,一般认为,像性能这样的基础工作,做得再好也往往不像开发出产品新功能那样显眼,因此,大家容易到了开发后期或性能出现问题时才开始解决。然而那时程序架构早已不容易更改,后续版本的性能优化也比较难,如果出了性能问题,解决的代价往往比较高昂。
现在,Office功能团队已经能够充分意识到性能对产品就像地基一样重要和优先,把产品的性能,安全等基础质量和自己的业绩评估挂钩并且层层挂钩下去,在产品设计一开始就充分评审讨论基础的质量,在开发周期全程留出人力密切监视基础的质量。功能团队开始关注性能,从被动看数据到主动向我们要数据。
总之,好的性能乘以好的功能才能保证产品的成功,两者缺一不可。让我们通过性能开发周期来保证软件的成功以获得持久发展吧!
★★征稿★★
寻找100个年度最具价值的实践案例
我们只要案例干货,拒绝广告
成为特约作者,你将:
◆ 连接100名年度经验与增长值TOP100的研发精英
◆ 提前入围「壹佰案例」年度最优案例榜单
◆ 案例整理成册,出版发行图书
◆ 成为msup客座教练
◆ 以观察员身份受邀出席壹佰案例
◆ 所在公司享有msup活动优惠
有意者联系壹佰案例主编Cynthia
邮箱:fang.cheng@msup.com.cn