In this article, I analyze the version 87.0 of the Facebook.app for iOS.

6 months ago I analyzed the version 66.0 of the Facebook.app for iOS: https://blog.timac.org/2016/1018-analysis-of-the-facebook-app-for-ios

The version 66.0 was a 165 MB app on an iPad Air 2 (64-bit). It was a monolithic app with its main binary being more than 100 MB.

The version 87.0 is now available: 253 MB on the same iPad Air 2 with only 64-bit code. In just 6 months, the Facebook.app size grew by 88 MB!

Let's see what changed…

App content

Looking at the app content of the version 87.0 using GrandPerspective gives a good overview:

Here is how the content of the version 66.0 looked like:

As you can see, the Facebook.app has been completely restructured:

the main binary is now only 19 MB

there is a huge 136 MB framework FBSharedFramework

there is another 26 MB framework called FBNotOnStartupPathFramework

…

Duplicated resources

One of the reason the app size grew is due to multiple copies of the same resources inside the app.

unetshallow_init.pb

You can actually see in the previous screenshot 3 copies of the same file unetshallow_init.pb :

Facebook.app/Frameworks/FBNotOnStartupPathFramework.framework/opticalflow_resource/unetshallow_init.pb

Facebook.app/Frameworks/FBSharedFramework.framework/opticalflow_resource/unetshallow_init.pb

Facebook.app/opticalflow_resource/unetshallow_init.pb

Keeping only one copy would save 7.2 MB.

DataFiles

Similarly the DataFiles folder appears 3 times. Keeping a single copy would save around 2 MB:

Facebook.app/DataFiles/

Facebook.app/Frameworks/FBNotOnStartupPathFramework.framework/DataFiles/

Facebook.app/Frameworks/FBSharedFramework.framework/DataFiles/

FBFacecastTipJarResources

Some resources called FBFacecastTipJarResources appear to be duplicated no less than 6 times in the app! The FBFacecastTipJarResources resources only take 150 KB on disk but 6 times makes 900 KB.

One example:

Facebook.app/FBFacecastTipJarResources/sent.m4a

Facebook.app/Frameworks/FBNotOnStartupPathFramework.framework/FBFacecastTipJarResources/sent.m4a

Facebook.app/Frameworks/FBNotOnStartupPathFramework.framework/sent.m4a

Facebook.app/Frameworks/FBSharedFramework.framework/FBFacecastTipJarResources/sent.m4a

Facebook.app/Frameworks/FBSharedFramework.framework/sent.m4a

Facebook.app/sent.m4a

Other duplicated resources

There are a bunch of other duplicated resources, amongst them:

modelMetaData.bin: 4 x 1 MB

schemaMetaData.bin: 4 x 830 KB

FBCommunicationSoundKit.bundle: 3 x 741 KB

MNSounds.bundle: 3 x 528 KB

FBSoundControllerResources: 3 x 500 KB

RelaySchema.json: 3 x 319 KB

libPhoneNumber.bundle: 3 x 172 KB

CACerts.plist: 3 x 168 KB

FBFacecastBroadcastKitResources: 3 x 98 KB

Montserrat-SemiBold.ttf: 3 x 70 KB

ReactMobileConfigMetadata.json: 3 x 33 KB

FBEntityCardsModuleResources: 3 x 33 KB

add-photo@2x.jpg: 3 x 29 KB

FBFacecastWithKitResources: 3 x 20 KB

FBNativeArticleEngagementActionsResources: 3 x 20 KB

FBFeedbackReactionsKitResources: 3 x 12 KB

These listed resources count for 15.5 MB. By removing the duplicated resources, you could save at least 10 MB.

Duplicated images

The Facebook.app contains 3 assets.car files:

Facebook.app/Assets.car: 11.3 MB for 2267 items

Facebook.app/Frameworks/FBNotOnStartupPathFramework.framework/Assets.car: 10.3 MB for 2126 items

Facebook.app/Frameworks/FBSharedFramework.framework/Assets.car: 9.5 MB for 1972 items

All the 1972 images in FBSharedFramework are inside the main Assets.car and also part of the FBNotOnStartupPathFramework Assets.car. So there are 3 times the same 1972 images taking 3 x 9.5 MB = 28.5 MB.

Keeping a single set of these 1972 images would save 19 MB.

The remaining images in the main Assets.car (2267 - 1972 = 295) and in the FBNotOnStartupPathFramework Assets.car (2126 - 1972 = 154) are unique.

New localizations

The Facebook.app gained 5 new localizations, increasing the app size by 4.2 MB:

hi.lproj (1.3 MB)

hr.lproj (692 KB)

hu.lproj (750 KB)

ro.lproj (709 KB)

sk.lproj (713 KB)

Also each localization got a new 12 KB file called AdsCountriesConfig.json . This adds 336 KB.

DO_NOT_USE_OR_YOU_WILL_BE_FIRED

When analyzing the version 66.0 I completely missed some amusing Objective-C interfaces, protocols and methods:

@protocol FBDeprecatedAppModule_DO_NOT_USE_OR_YOU_WILL_BE_FIRED

@protocol FBLoginFacilitatingAppModule <FBDeprecatedAppModule_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>

@interface FBTimelineModule : FBNativeAppModule_DO_NOT_USE_OR_YOU_WILL_BE_FIRED

@interface FBNotificationsModule : FBNativeAppModule_DO_NOT_USE_OR_YOU_WILL_BE_FIRED

@interface FBProductionLockoutModule : FBNativeAppModule_DO_NOT_USE_OR_YOU_WILL_BE_FIRED

@interface FBSearchModule : FBNativeAppModule_DO_NOT_USE_OR_YOU_WILL_BE_FIRED

…

__RODATA segment

Although the main binary is much smaller than the App Review limitation, the Facebook.app still uses a __RODATA segment containing sections generally found inside the __TEXT segment. For more information about it, please look at the previous post https://blog.timac.org/2016/1018-analysis-of-the-facebook-app-for-ios.

Conclusion

Between version 66.0 and 87.0, the Facebook.app has been completely restructured. The main -and only- binary has been split in several frameworks.

It appears however that during this process a couple of resources have been unnecessarily duplicated:

opticalflow_resource: 3 x 3.6 MB

DataFiles: 3 x 1 MB

images: 3 x 9.5 MB

FBFacecastTipJarResources: 750 KB

Other duplicated resources: 15.5 MB

Removing the duplicated resources would save at least 40 MB. This partially explains why the app size has increased by 90 MB.

Update 15.04.2017: Facebook.app for iOS [v. 88.0] cleans up duplicates