
前言
这次的 WWDC17 又放出了许多干货来帮助开发者更好地开发 app。精彩的内容特别多,本篇主要关注的是《Writing Energy Efficient Apps》 中所介绍的一些关于如何让 app 节省电量的内容。
正文
以下是本次演讲的主要内容。先讲一下本次演讲的概述。
概述
-
Why(为什么要关注 app 用电情况) -
What(一些概念) -
How( 代码层面的一些建议、利用工具的性能检测)
Why
为什么我们要关注自己开发的 app 所消耗的电量?先放个图。

如图,用户可以在
设置-电量 查看过去24小时及七天,自己 app 耗电情况排行榜。如果你的 app 不幸在列表中名列前茅,然而如果这个 app 并不像微信那样会被重度使用时,那挑剔的用户就会认定这是一个极其耗电的 app, 然后极有可能删除这个 app 。显然,我们作为开发者是不希望碰到这种窘境的。因此,我们非常需要关注自己 app 的电量能耗情况是否合理,以此提升用户体验,避免 app 被删除的厄运。
What
-
一些概念(还是上图解释)
`x 轴`为时间,`y 轴`为电量消耗的坐标图
Idle状态说明 app 处于休眠状态,几乎不使用电量。Active状态说明 app 处于前台工作状态,用电量比较高,我们可以看到图中的第二个Active的耗电远高于第一个,这主要因为 app 实际所做的工作类型不同而导致的。Overhead指的是调起硬件来支持 app 功能所消耗的电量(原文是 bring hardware up)。note:如果你的 app 就算只做了一点点事,Overhead所带来的电量消耗都是一点不会减少的!
图中,横线以下所包区域是固定开销(Fixed Cost),横线以上区域是动态开销(Dynamic cost)。 -
耗电的四大天王
-
CPU 处理(Processing) -
网络(Networking) -
定位(Location) -
图像(Graphics)
-
-
节省电量的四个基本原则-
Identify想清楚你需要 app 在特定时刻需要完成哪些工作,如果是不必要的工作,考虑延后执行或者省去。 -
Optimize优化 app 的功能实现,尽可能以更有效率的方式去完成功能。 -
Coalesce意为合并。 -
Reduce减少做重复工作的频率。
-
How
-
Networking(网络)
演讲者举了一个社交 app 的例子,这个 app 具有MainFeed(类似刷新出微博的信息流)、上传照片、上传用户分析统计数据3个功能。- MainFeed
原先的做法:创建了一个定时器,定时去重新加载刷新数据。这样就会导致 app 会不断重复刷新内容。
改进前
改进:1.去除定时器,只在产生用户交互响应(例如下拉刷新、点击按钮等)、收到新消息时去重新加载数据。2. 使用 NSURLSession 的WaitsForConnectivity属性,查了一下 API(Causes tasks to wait for network connectivity to become available, rather than immediately failing with an error,让任务等待到有网络再执行,而不是立刻报错)3.使用缓存(避免重复请求获取相同的内容)
改进后 - 上传照片
原本的做法:当用户上传照片后,立刻向服务器发送照片,一旦上传失败,就不断重试上传。
超时时间长,长时间处于高能耗状态
改进:1.减少重试次数2.设定合理的超时时间3.批量上传照片(当累计了一定数量的照片后,一起上传) 4.使用 Background Session(仅当重试次数达到上限)。
超时时间短了,能耗降低 - 上传用户分析数据
强推使用NSURLSession Background Session,它的好处有自动重试、全程监控,全新的属性包括了Start time、Workload size,帮助 app 知道工作的最佳时机(Indicate system the best time to do your work)。 - 小结:1.
保证没有重复的工作2.使用 background session3.使用批处理4.减少重试次数
- MainFeed
Location(定位)
介绍了一大堆定位 API,包括了Continuous location、Quick location update、Region monitoring、Visit monitoring、Significant location change。
其中Continuous location保证了定位功能的持续性,防止设备休眠。因为我的现有开发比较少接触到定位方面的功能,对于不太 API 熟,因此不多讲述。有兴趣的童鞋可以看一下这两个 API CLLocationManager、CLLocation 。
小结:1.清楚 app 需要的定位精确度(适合你的需求就好) 2.使用其它来替代 Continuous location(因为这个比较耗电) 3.不需要使用定位时,就停止4.延后定位更新Graphics(图像处理)
两条建议:1.保证在 UI 真的需要有变化时,进行屏幕更新(Minimize screen updates Ensure screen updates provide needed changes) 2.避免blur(Review blur usage Avoid placing blurs over updating elements)
关于 MacOS简单提了下尽量少使用独立显卡,只在动画性能吃紧、或者其独有功能时才去使用它。-
CPU-
明确 app 要完成的任务(Identify tasks) -
更高效地完成任务(Do work quickly and efficiently) -
不要使用定时器(Avoid timers) -
给一点余地(如果必须要设置一个定时器,设置比较长的间隔时间)
-
-
Background Processing(后台处理)-
快速完成任务(Finish work quickly) -
使用后台 app 刷新 API(Use background app refresh) -
调用 completion handler(Call completion handler)PushKit API 现在有 completion handler了,处理完推送后会调用的!前后对比图,让 app 更快进入空闲状态。
使用 completion handler 之前
使用 completion handler 之后
-
-
Debug 工具使用介绍
照例先强调了 tools 的重要性。正如文章开头所讲,用电量大的 app 容易被用户删除...所以我们必须用好这个工具。-
调试界面组成部分
连接 Xocde 调试,选择 debug 选项。
可以看到如下界面
可以查看你的 app 在设备的CPU、内存、电量使用、硬盘、网络的使用情况。点击Energy Impact查看电量情况。
接下来专注右边的区域
先看左上角
如图,指针所指向的半圆环分为三部分,代表的是 app 的总体上的平均消耗电量评级,low(绿色区域)、high(黄色区域)、very high(红色区域)。通过这张图,我们可以大致了解 app 电量的使用情况。理想的状态是 app 处于low、high状态。但是通常情况下,如果我们进行过优化,app 会处于high、甚至very high状态。我们需要更深入地知道究竟哪一部分的功能导致耗电量大涨。继续往下看。
这张饼图能让我们快速了解各耗电部分的占比。里面包含了前文提到的耗电的几个部分,包括CPU、网络、定位、GPU、Overhead。
接下来看中间部分(noteXcode 9 更新)
x 轴为时间,y 轴为用电量的坐标图
柱状图中,其中每根柱子代表了每秒钟的耗电情况。每根柱子都由不同颜色的矩形块堆叠而成。依次是Overhead(红色)、CPU(蓝色)、网络(深黄)、定位(淡黄)、GPU(绿色)、后台(深灰)、前台(淡灰)、Suspend(白色)。
如上图所示的最右侧,可以看到各部分的用电情况占比。这意味着可以一边操作 app,一边查看设备的各部分耗电情况。举个例子,当你期望你的 app 只需要有 CPU、网络方面的功能,运行起来之后却发现有一部分的电量是因为定位功能而损耗的!这显然是你所不希望的。你肯定想去看看究竟是什么坑爹的原因造成了定位的耗电。怎么查呢?再往下看。
如果你觉得CPU、网络、定位这几个方面耗电情况让你不满意的话,点击Time Profiler、Network Profiler、Location Profiler这三个按钮的其中之一,Xcode会帮你断开调试连接,并启动Instruments来分析 app 性能。
比如点击Time Profiler,可以帮助查看你的方法耗时情况,从中找出最耗时的方法,然后优化。
-
使用场景
启动空闲后台-
特殊:如导航类 app 的话,可以对其中的导航相关功能进行检测。直播类 app,对直播间进行检测。
-
最后的总结(Final Thoughts)
- 1
使用 NSURLSession Background Session(处理后台工作) - 2
尽量减少使用 continuous location(因为持续定位太耗电!) - 3
避免使用定时器 - 4
合并(一起重复的工作一起执行,减轻负担) - 5
使用 energy gauges(即Xcode 的内置 tools)
小尾巴
希望这篇文章能帮助到那些对通过优化 app 节省设备电量相关知识还不太了解的同学。如果你对这方面感兴趣的话,赶紧安装 Xcode 9 ,动起手来!因为其中一些调试功能只在 Xcode 9 中有所体现。第一次如此码这么多字,可能在表达方面存在缺陷,如果有看不懂或其它不尽如人意的地方,敬请告知,谢谢!



















