@Rays
2017-08-04T17:19:03.000000Z
字数 3042
阅读 1632
语言开发
本文最初发布于Halide官方博客,原作者:Ben Sandofsky。经授权由InfoQ中文站翻译并分享。阅读英文原文:One Weird Trick to Lose Size。
你可能不知道的是,有些广为使用的社交网络App包大小达到了惊人的 400MB。如果每周发布一个新版本的话,一年下来用户将要下载 20GB 的数据。
自发布Halide以来,我们收到的最出乎意料的点赞是关于该App的大小。Halide约11MB,我们一年所推送的数据要少于那些社交网络App一次更新就要推送的数据。
有朋友会问:“难道你们没有使用Swift吗?”。Swift会将自己的标准库捆绑到你的App中,这将增大App的大小。Halide几乎是完全采用Swift 开发的。
那么我们是怎样做到App瘦身的?让我们首先给出一点技术相关的内容。虽然它们主要来自对QA1795的概述,但是这些内容很重要。
QA1795:Reducing the size of my App
https://developer.apple.com/library/content/qa/qa1795/_index.html
从Xcode中导出构建。在Xcode中选择“Save for Ad Hoc deployment.”。如果App支持“app thinning”(当前的App应该都支持),选择“Export for Specific Devices.”。确保你勾选了“Rebuild from bitcode”选项。
这样做,我们不仅能得到App软件包最终的大小,而且还能得到一份“App瘦身报告”。依此报告去检查App软件包,找出其中最具影响的问题。
将资源(Asset)保存在Asset Catalog中。在上传App时,Apple会将其切分为特定于设备的版本,具有两倍尺寸屏幕的设备不会得到三倍的资源,反之亦然。
在将资源置入Asset Catalog前运行pngcrush工具。根据QA1681介绍,Xcode将自动为处于Asset Catalog之外的PNG压减资源。
将UI资源及类似条条框框限定为PNG,App中的大部分资源很可能由此构成。但是如果资源中有一些照片,尝试一下JPEG。稍加压缩就非常有助于App瘦身。
完成这些工作难点,只会对上百M的大块头App取得数M的瘦身效果。我不知道该怎么婉转的告诉你,但你需要的是减少代码量。
Halide具有约一万五千行Swift代码,其中包括:一个实时视频处理器、大量的用户控制,以及我们的平台控制AVFoundation。我们关注的是并非由我们自己编写的代码。
我借助Auto Layout削减了上千行的模板代码。很多开发人员依然执着于使用手工布局。可能他们对Auto Layout并不甚了解,或者由于他们辗转从他人那里听说Auto Laytout的性能堪忧(虽然事实并非如此)。
我已经看到太多的开发人员致力于开发内部使用的布局引擎,尤其是在一些大型企业中。这太疯狂了。Apple在操作系统上绑定了精细的布局引擎,因此不要使用定制框架,这会导致App规模膨胀。
如果弃用Interface Builder(IB),我们可以再削减100K大小。用户手册和设置页几乎完全是使用IB搭建的,使用了一些简单的约束。Camera UI高层布局的管理也类似。虽然减掉100K很诱人,但是出于对短期内生产效率的考虑,值得让这一部分保持原样。
如果查看一些大型App的软件包,我们将会发现其中存在数十个第三方框架,大小从100K到数兆不等。
我并没有使用第三方软件库。虽然这有些走极端,但是我们的情况有些特殊。
这是因为并没有多少第三方软件库能适合我们的需要。在iOS开发社区中,有很多人在做JSON的映射,但是没有人关注对DNG文件的底层操作。
那么我前面所提及的视频处理的情况又如何?我能听到读者喊出来:“可扩展GPUImage实现!要自己造轮子,难道你疯了!”
就我自身在Periscope技术栈的工作经验而言,从GPUImage转到自己的内部解决方案将会收益颇丰。GPUImage完全适用于不需要实时图像处理的业务。但是出于对Halide的长远考虑,我们需要实时渲染的功能。自建该组件是十分重要的。
因为GPUImage文件的规模,我从未考虑过它。我们自己造轮子,避免了在App中绑定125种不会被使用的过滤器。
在替代画蛇添足的大型框架问题上,PSPDFKit具有异曲同工的成功之处:
很高兴宣布,我们使用PSPDFKit 6.8 for iOS重写了数字签名的核心实现,这改进了检测、验证,并给出了更好的错误报告。依此,我们还想方设法完全去除了对OpenSSL的依赖。这一过程削减了我们二进制程序的规模。
不要染上“不需重造轮子”的症状,我们有充分的理由避免使用软件库。
我们不使用任何第三方分析或是崩溃报告服务。首先一点,我们很反感向广告商发送用户数据。不过我们先不谈理想情况,看看现实是怎样的。
数据并非是凭空产生的。在大型App中,每个行为都会记录为一个分析事件。大型App需要日志架构,去唯一识别用户、请求去重、日志缓存,并在失败时重试,诸如此类。这些加起来,代码量自然上去了。
A/B测试更为恶劣。一个典型的社会网络App中充斥着非活动的A/B测试,没有人会回过头去清理干净。
避免分析和 A/B 测试的出发点并非是考虑到代码膨胀,这是我们的产品哲学。知道过多数据会改变你的主意。你发现自己疲于为大众用户做优化,而非在对真正能带来可见的变化而放手一搏。
基于这些原因,我们仅使用 Apple 分析。它工作良好,无需对代码做任何更改,并且是免费的。它尊重用户的隐私,需要用户主动参与。我们的用户选择参与率是32%,完全适用于我们的需要。
Apple分析需要你设置时间和地点。曾经我们并不确定应用最优价格,因此我们利用Apple分析做了一些试验。但是,我们对业务驱动的分析和产品研发间作了严格的区分,避免打扰后者。
我们是一个两人组成的团队,通过销售产品而营利。我们的成长是完全健康的。如果得到用户的喜欢,他们会帮我们口口相传。我们乐于提供小型App,我们认为这也会使用户开心。
我们的建议并不能对那些极大膨胀的App起到帮助。因为社交网络需要从广告商处谋利,而广告商则需要详细的分析用于广告定位。
大型App会具有上百名开发人员,他们组成了数十个团队,每个团队具有独立的季度目标。开发人员走得越快,实现了更多的目标,就越可能得到提拔。
这种考虑是可以理解的:“该软件库会节省我们一个星期的时间,但会对App增加一兆大小。那好,既然该App已经上百兆了,再增加一兆又何妨?”
大型企业充斥着一些这样的会导致未知结果的看上去“合理”的想法。
特性的交付并不会使一个开发人员得到技术职位上的升迁,而构建一个新的布局引擎则会。而记录了这些复杂技术的博客甚至被企业作为招聘的亮点。
唯一的解决方案是让高层领导给出声明:“我们将要对App瘦身”。不幸的是,技术CEO不会去使用只有8G存储的iPhones,他们也不会在网速恶劣的地区居住。
这并非毫无回报的事情。自交付Halide以来,我们已经收到来自全球用户的大量消息,感谢我们保持App的小型化。
聚焦于客户是App瘦身的唯一可信理由。