BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

Facebook iOS App技术演化十年之路

| 作者 覃超 关注 2 他的粉丝 发布于 2016年9月9日. 估计阅读时间: 14 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

本文根据覃超在2016GMTC全球移动开发大会上的演讲整理而成。

非常荣幸和大家在这里见面,利用这个机会给大家做分享。我之前在Facebook一直做技术开发,现在我将回顾Facebook十年的发展经历,包括:最初iOS 2.0和Facebook App 1.0上线,从iOS App转型到HTML5和Hybrid App,其中遇到的各种问题和学习到的经验。

引言

首先做一个简单的自我介绍。2011年,我加入Facebook做软件开发,最初做 Facebook Phone:那是非常大的项目,由我们的CTO Bret Taylor 亲自主持。后来,三年多的时间里,我得到一个启示:“无论在大公司还是在小公司,项目失败是非常正常的一件事情,而你要做的就是继续坚持。没有人会记住你失败的惨痛,只会记住你后面的成功。”后来我们参加了 Messenger 开发的整个过程,我用 iOS 原生开发做了很多功能,比如语音消息(Voice Message)、大表情(Sticker)、免费话(Zero Rating),还有提高消息收发的效率和稳定性等。

为什么要解剖和分析Facebook App?

首先回顾一下Facebook这10年发生了什么。十年前,iPhone 4还没有诞生,换成HTML5之后,那时的名字叫Faceweb,原生就是一个壳,用网页来取代原生做了一套App。

现在这个版本全部围绕着原生,另外还加了一些模块化和React Native。给大家总结10年Facebook的发展,希望是“师夷长技以制夷”,中国的开发者可以从中学习。

从上图可以看到,在欧美板块,Facebook一直处于领先位置。首先问大家一个问题,猜猜Facebook有多少工程师?几百人、或者几千人?这个App实际上非常大,有123MB,用户基本上不敢在运营商网络里面下载。当时我们的App也是开发软件最多的。很多工程师其实做得并不是特别好,但是又把很多代码加进去。这是一个比较负面的例子,因此大家不要觉得Facebook太牛逼。

Facebook iOS 工程   

现在,Facebook APP团队有一千名以上的工程师,光给这个App塞代码的人有一千多人,三年前就有六、七百人。我们之前用 Git 来做代码管理,工程师越来越多,Git History也越来越长,导致Git各种操作奇慢无比,后来就转用Mercurial(HG)来进行代码管理。在依赖和模块管理方面,Facebook自己开发了一个叫Buck的软件,相当于大家所用的Cocopods。这个Cocopods 是非常重要的。另外,每个组负责自己的产品线,每个组管理自己的模块。你的组越来越多的时候,移动的App越来越多,怎么规模化起来?我们用的办法就是基于模块。最后,公司大了之后,数据层面最重要一点就是不可变。

图中内容比较多。我们只有一个iOS Code Repository。

左边是目录打开的第一页,没有任何文件,就是一批目录。APPs打开进去,左侧可以看到经常用的软件和开源项目。当你去一个比较大的公司,怎么比较好地规模化管理你的团队?我们的经验就是,把它分成非常小的模块,并共享,每个人管理自己的模块,同时还有一些公共模块。

大家做开源的都知道,Apple官方开源了FBReachability。我们稍微改了一下,有FB,你们一起合作开发的系统的话,尽量做 Shared Libs(以library为主的开发)。

Facebook App有123MB,各种App加在一起,是1190万的规模。Facebook整个代码库,估计是在6千万行代码左右。可以看到,Mac OS Tiger 操作系统的复杂度远大于这个。

比较有意思的是,最后这张图谷歌的代码,竟然有20亿行。

Facebook iOS App简史

Facebook App 这10年发展经历了很多事情,概况起来有三点。第一,从原生走到HTML5,然后承认HTML5犯了很大的错误,最后再回到原生。第二,怎么管理好你们的团队。第三,介绍我们的模块,基于模块化的编程,最后是React Native。

Facebook 1.0

现在大家和我一起回到2007年,发布Facebook 1.0 App的时代。那个时候,手机App非常少,做App移动创业是非常及时的。你会看到,下面图中所示也是很多App在移动端。

也许大家很熟悉图中的App。这个App是由Joe开发的,可以看到当时那个年代移动开发的特点。Joe不是做移动开发,基本上是做前端开发的,或者是网页开发的。他是大名鼎鼎的 Firebug 的作者,Firebug被Chrome借鉴成 DOM inspector。后来 Joe 加入Facebook后单人开发了 Facebook App 的前几个版本,当年iOS库很不完善,所以 Joe 把自己写的很多UI代码开源出来,就是叫做Three20的一个框架。比较老的开发人员应该听过这个,在那个年代非常复杂,UIKit 也不是特别好。而且你要是看那个App,你会发现,这10年来,基本上利用Three20最大带动的就是UIKit。

回顾一下那个年代,我们称为拓荒时代,激发了一代人。Apple SDK,现在已经耳熟能详了。另外一方面,你可能要感谢各种开发工具。

Facebook 2.0

接下来我们看一下Facebook 2.0的概况。有几个特别牛逼的人想到了一个计划。整个Facebook公司,其实就是网页、网站的基础,当时他们取了一个名字 Faceweb,其实就是HTML5一统江山。当时安卓分化越来越严重。相同的代码要切很多份,iOS 要写一份,安卓要写一份,主站要写一份,还有移动网站 m.facebook.com 也要写,特别麻烦。

首先剖析技术细节。Facebook全部用HTML5的网页,有几个理由。第一,因为HTML5更方便,iOS代码比安卓方便很多。第二,你写了很多的代码,最后分析,就可以不用APP Store。最后发现什么问题?我们的App基本上都是新的,但是苹果选项里面必须要选。

在2012年,扎克伯格自己亲口承认,过多的赌注压在HTML5上面是最大的一个错误。对于整个公司来说,这是非常遗憾的。一个经验教训是,有一些技术说起来简单,但是做起来不可行。首先,这种跨时代的东西,比如HTML5出来的时候,也出现了这个问题。你要写JS Bridge,这样导致体量越来越大。接下来,会发现Bridge Framework代码非常乱,每个平台上UI都要妥协,在每个平台都不太好看,或者不是特别好用。最后,前端工程师最讨厌的一个问题,就是浏览器非标准化、不兼容。因此,移动开发也要考虑兼容相关的问题。

另外,我们做了这么多投入,所有技术的复杂度是客观存在的。你所要做的事情是,如何运用公司的方式,去解决客观的复杂度。如果想偷懒,最后你会发现你会吃不了兜着走。最关键的一点,当时APP并不是为用户量身打造,而是为我们的工程师所考虑。这些都是问题。所以,你的产品战略要为用户的体验为出发点,而不是因为某个技术如何牛逼而选。

Facebook 3.0

接下来我们到了3.0时代:从全原生来重写App。当时在 Facebook Engineering Blog发布了一篇官方文章,强调了FB的工程师的确在 XCode 里边建了 New Project,还用了异步渲染(async rendering)的技术。下一个版本的时候,把异步渲染取消掉,7.0版本出来之后扁平化了,成为了现在这一版,基本上和主流App一个模样。到了 Kimon 和 Scott 时代,这两个工程师非常牛逼,他们开发了 Paper App,由此开源出 POP animation库。最主要的是,只要用户交互比较多的时候,我们全部用延伸来实现。

我们在异步渲染上栽过跟头。早期我们发现UI和Layout计算是最卡的地方,于是各位天才的工程师们又做了一个5.0,想在非主线程里面做一个渲染。当时Facebook采用CALayer来做异步渲染,Apple对CALayer的文档说明是线程安全的。可是最后发现Apple文档完全写错了,文档和代码根本不一样,又踩了一个坑。因为线程文档的Bug,导致新Facebook App大概20%的崩溃比例,用半年的时间来完完全全解决全部的问题。另外,开始我们用了Core Data。如果是比较小的创业团队,或者公司规模不大,完全可以用 Core Data。但是到了工程比较大的时候,会发现Core Data性能非常差,耗时特别长。同时还有一个问题,如果数据模型特别多,管理起来将有非常大的系统问题。

当代的Facebook iOS   

现在我们的Facebook基本上就是中规中矩。整个苹果已经比较完善了,各种功能也比较齐全了,而且硬件已经发展到一个特别成熟的时期,同时6S出来要加很多 3D touch 的东西。我们的APP形态,90%都是原生的。我们有一个单人独立开发的小项目,我们很积极尝试着React Native,但是我们的代码现在还没有用。如果公司比较小,可以先去尝试React Native。

最后是整个Facebook iOS团队的组织架构。如果移动开发团队比较大,也可以考虑这个架构,就是基于模块的开发组。首先,Facebook的iOS组是怎么样子?整个移动开发基础组件有个iOS 架构组(后来改名叫 iOS 核心组),里面就有一些比较资深的大牛,他们要做的就是衡量App 的架构好不好,会经常用到一些库,比如FBNetworking、FBMemModel等。

还有一个功能的团队,做自己的功能开发,有做网页的,也有做iOS,也有做安卓的,每个人做自己的模块开发。最上面还有App发布组。我们有很多工具,类似 fir.im、 蒲公英、Jenkins。开发周期是四周一次,每个版本在月底从主分支切出去,然后变成一个候选版本分支,之后再进行测试(四周测试)发出去。

整组的协同是基于模块开发的。每个功能团队维护自己的模块,模块之间互相通信的时候使用类URL的方式。每个模块在启动时,直接在模块管理上注册。于是后续这个模块就一直监听着属于它处理的URL。

同理,每个功能小组都有自己的模块,每个模块都有自己的组,一个组有几百人,有的几十人,甚至上百个不等。我们的代码都是共享的。

HTML5 还是100% Native  

最后想谈谈HTML5。任何一门技术出现都是这样的曲线,刚开始的时候还不错,大家都很狂热,原生跨时代,最后发现问题,大家热度下降,最后就变成失望。现在对于React Native 、 HTML5或者原生态,可能也会经过这么一个过程,大家要有所准备。大家可能在这个过程中的不同位置。

HTML5技术开始非常火热,在2011年的时候,都在吹嘘HTML5会改变世界。现在慢慢冷静下来,也到了一个比较好的新阶段。所以你们的程序要怎么开发呢?我建议,外面用壳,里面的内容视情况而定。如果交互性非常强,用户体验非常高,那不用想了。如果是展示为主,比如说美团、淘宝,基本上都是展示各种各样的信息,那么全部可以做。所以现在,Facebook并不会对HTML5判死刑。

小结

最后总结三点。首先,大家要做App,第一肯定需要壳,里面的信息视情况而定。其次是Mobile里面要做一些优化。最后,至于React Native,Facebook没有用,大家要保持非常警惕的心态。


感谢陈兴璐对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ@丁晓昀),微信(微信号:InfoQChina)关注我们。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT