iOS Dynamic Framework 对App启动时间影响实测

最近看到的Slow App Startup Times里提到:

The dynamic loader finds and reads the dependent dynamic libraries (dylibs) used by the App. Each library can itself have dependencies. The loading of Apple system frameworks is highly optimized but loading your embedded frameworks can be expensive. To speed up dylib loading Apple suggests you use fewer dylibs or consider merging them A suggested target is for six extra (non-system) frameworks.

至于什么是static lib什么是dynamic lib这里就不展开提了,大家可以通过在文章底部的相关链接去详细了解。

引用一下官方的解释就是:

  • A better approach is for an app to load code into its address space when it’s actually needed, either at launch time or at runtime. The type of library that provides this flexibility is called dynamic library.
  • When an app is launched, the app’s code—which includes the code of the static libraries it was linked with—is loaded into the app’s address space.Applications with large executables suffer from slow launch times and large memory footprints

如果给你一个简单的概念就是如果你的framework使用了swift就是dynamic lib。这也是本文要对比的主题:动态的framework对app启动时间影响到底多大。

测试的方法就采用 iOS 10 提供的新的环境变量 DYLD_PRINT_STATISTICS 输出的app启动时间。Xcode的版本是8.1,测试设备是iphone 6。cocoapod版本1.1。

注意,测试过程发现每次获得的时间统计都不一致,所以我这里的数据可能和你自己测试得到的不同,但是我认为这种偏差不影响定性。

基准线:空的OC项目 VS 空的Swift项目

创建两个没有任何业务逻辑的空的项目。


纯OC项目的启动时间
纯swift空项目的启动时间

大概有10毫秒的差异。这个差距考虑到测量的偏差可以认为两者几乎是一致的。

但是有时会出现swift加载忽然提高到400ms的情况。这是因为系统的动态framework只会加载一份。假设10个app启动都用到了UIKit,系统内部也只加载了一份UIKit。所以有时swift项目启动的时候刚好用到了系统framework没有缓存,就会显得的长一点。

6个framework

现在我们对比有代码的情况。两个项目分别加入5个依赖。
这是OC项目的6个依赖:

  pod 'AFNetworking', '~> 3.0'
  pod 'Masonry'
  pod 'MJRefresh'
  pod 'SDWebImage'
  pod 'MBProgressHUD'
  pod 'IQKeyboardManager'

这是swift项目的6个依赖,为了模拟真实生产中依然使用一些OC库的情况,将3个库换成了swift编码的,保留了3个OC库:

  pod 'Alamofire'
  pod 'SnapKit'
  pod 'MJRefresh'
  pod 'Kingfisher'
  pod 'MBProgressHUD'
  pod 'IQKeyboardManager'

OC的启动时间在70-100ms左右。这里取快的情况的数据:


OC6个依赖的启动时间

swift项目在第一次安装时的启动时间在dylib会多100ms,不知为何。swift项目在已经安装后运行打开的成绩:


swift6个依赖

列一个横向对比图:

结论

swift项目的dylib时间相比OC多了一百多毫秒,远远大于OC。

Swift 不使用framework VS 使用framework

我们猜测是不是加载framework导致时间增大很多呢。所以我们把这些依赖的代码全部放在主app里,不使用framework分离。这次我们把几个依赖的库全部换成swift:

  pod 'Alamofire'
  pod 'SnapKit'
  pod 'Kingfisher'
  pod 'SwiftDate'
  pod 'ObjectMapper'

5个依赖的项目在app已经安装,运行打开结果:


5个依赖

考虑到误差可以认为framework里的代码是OC还是swift对于加载时间的影响并不大。
把依赖的代码全都合并到App里,就是采取手工拷贝的方式:

安装后打开的启动时间统计:



对比图:


结论

如果把代码收到拷贝进app里,可以显著降低dylib加载时间。

15个framework OC VS Swift

OC的podfile:

pod 'AFNetworking', '~> 3.0'
  pod 'Masonry'
  pod 'MJRefresh'
  pod 'SDWebImage'
  pod 'MBProgressHUD'
  pod 'IQKeyboardManager'

  pod 'FMDB'
  pod 'GPUImage'
  pod 'OpenUDID'
  pod 'DateTools'
  pod 'TMCache'
  pod 'WebViewJavascriptBridge'
  pod 'ZBarSDK'
  pod 'JSQMessagesViewController'
  pod 'YYKit'
  pod 'DZNEmptyDataSet'

swift项目的podfile:

pod 'AFNetworking', '~> 3.0'
  pod 'Alamofire'
  pod 'SnapKit'
  pod 'MJRefresh'
  pod 'Kingfisher'
  pod 'MBProgressHUD'
  pod 'IQKeyboardManager'

  pod 'FMDB'
  pod 'GPUImage'
  pod 'OpenUDID'
  pod 'SwiftDate'
  pod 'CryptoSwift'
  pod 'ObjectMapper'
  pod 'ZBarSDK'
  pod 'CocoaLumberjack/Swift'
  pod 'YYKit'
  pod 'DZNEmptyDataSet'

OC的结果:



swift的结果:


对比图:


时间对比

纵向对比:


结论

OC的项目随着依赖增多,初始化时间增大,但是dylib时间增加不明显。swift则dylib时间大幅增加,初始化时间变化不大。总的启动时间比OC多了200多毫秒,随着framework的增多,启动时间差距拉大。

25个dynamic framework

如果把dylib提高到25个时间又会增长多少呢。
在15个基础上再添加10个依赖:

  pod 'EZSwiftExtensions'
  pod 'ReactiveCocoa', '5.0.0-alpha.3'
  pod 'RxSwift',    '~> 3.0'
  pod 'RxCocoa',    '~> 3.0'
  pod 'MonkeyKing'
  pod 'Reusable'
  pod 'SwiftyJSON'
  pod 'XCGLogger'
  pod 'Gifu',    '~> 2.0.0-rc'
  pod 'Spring', :git => 'https://github.com/MengTo/Spring.git', :branch => 'swift3'

运行时间:



和15个dylib的时候的对比:



dylib加载时间从400增加到600,增加了30%左右。dylib数量从15到25个增加40%。接近线性。

总结

毫无疑问,使用了dynamic framework后会增加app启动时间。如果你的数量在25个左右,相比OC的静态framework启动时间会增加0.5s左右。我个人对于iOS提高加载framework的时间不太抱有希望,苹果让自定义的framework常驻内存似乎也无望,这个时间短期内可能无法抹平。

如果人为的把一些外部依赖手动管理在一个framework也是可行,但是如果复杂一点包的互相依赖的情况会比较费心。

如果公司对性能有着苛刻要求可能500ms是难以忍受的。但是我觉得对于大多数产品而言,牺牲这500ms的性能相比于使用OC,我觉得还是用OC比较难受。

欢迎关注我的微博:@没故事的卓同学


相关链接:
WWDC 2016 Session 406 Optimizing App Startup Time
What are Frameworks?
iOS 开发中的『库』(一)
jverkoey/iOS-Framework

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 二十二 福冈圆梦 缘海终于还是要带着蓝去日本,完成他们最浪漫、最伟大、最难忘的婚礼,从爱开始的这一座城市寻找他们的...
    易写发阅读 336评论 0 1
  • 美一个永恒的话题,美景,美食,美女。美可以成为任何事物的形容词!我们每个人对美的定义也不尽相同! 就美女来讲,不管...
    穗苗阅读 204评论 0 0
  • 总是有人问我她怎么了。她怎么不说话,她怎么不出门,她怎么总躺着,她…… 我也不知道她怎么了,她变得很沉闷,她不在呼...
    想和你回家阅读 243评论 0 0
  • 不知何事萦怀抱, 醒也无聊,醉也无聊, 梦里何曾到谢桥。 出自纳兰性德的《采桑子》,包含了叶广岑两个中篇的名字。 ...
    小褶子乖乖阅读 1,145评论 2 0