Slide 1

Slide 1 text

QC Li / iOS Dev Reduce iOS app size By analyzing source code 

Slide 2

Slide 2 text

By Analyzing source code… Internal Modules Analyzed 3 Binary size Reduced 44% For LINE app Saved 2.1MB

Slide 3

Slide 3 text

Agenda › App Size › Link Map › Find Redundant Code

Slide 4

Slide 4 text

App Size Overview

Slide 5

Slide 5 text

› 📦 The space an app takes on the disk of user’s cellphone. › ⏳ It takes longer time to download or update an app with bigger binary size. App Size

Slide 6

Slide 6 text

App … 🗄 Database 📐 Storyboard / UI file 📚 Translation Text 🖼 Image 📃 Code

Slide 7

Slide 7 text

More code, larger binary size 📃 📦 📦 📦📦 📃 📃📃

Slide 8

Slide 8 text

When app size getting bigger… › Redundant code increases in app › More features ➡ Bigger size

Slide 9

Slide 9 text

How to find redundant code? › Like losing weight › We should have a scale first. › Can compare the weight change before and after. › May need to analyze body composition. › By removing redundant code, it can reduce app size.

Slide 10

Slide 10 text

Link Map Using link map as scale to analyze iOS app size

Slide 11

Slide 11 text

Link Map › An intermediate file generated by compiler. › Recorded the memory layout of an app by combining binary from other object file.

Slide 12

Slide 12 text

By default Xcode doesn’t generate link map but it is easy to turn this build option on. Generate it! Turn this on

Slide 13

Slide 13 text

Link Map Format › Path and Arch › Object files › Sections › Symbols › Dead Stripped Symbols

Slide 14

Slide 14 text

Object Files › Each object files (.o) is generated from source code by compiler. › There is an ID number for each object file in link map. Filename ID

Slide 15

Slide 15 text

› Memory layout › Address › Size › Summarize all sizes will get total size of the app. Sections

Slide 16

Slide 16 text

› Memory layout details › Address › Size › File — Object file › Name Symbols Symbol Object file ID Size

Slide 17

Slide 17 text

› Unique name for compiler usage. › Help to address corresponding code. › Use tool to get meaning. Mangling

Slide 18

Slide 18 text

What we learned from Link Map › Compare the size between components. › Observe the size change before and after. › Knowing the size of each component. › Down to source file level. › Combining object file list and symbol list from Link Map file.

Slide 19

Slide 19 text

Find Redundant Code By using SourceKit to analyze source code

Slide 20

Slide 20 text

Redundant Code Sample 1 Compiler warns about non-used variable

Slide 21

Slide 21 text

Redundant Code Sample 2 Non-used interface (var or function)

Slide 22

Slide 22 text

Redundant Code Sample 3 Referenced but not really in use

Slide 23

Slide 23 text

Redundant Code › Unreferenced declarations › How to find those unreferenced declaration? › Variables or functions that are not in use

Slide 24

Slide 24 text

Find Unreferenced Declaration › Use “Find Call Hierarchy” in IDE. › Compiler have those information. › We could analyze compiler intermediate steps › Is there a systematic, lightweight way?

Slide 25

Slide 25 text

SourceKit › Open source by Apple › Swift language tool › IDE supports › Indexing › Syntax highlight › Code completion

Slide 26

Slide 26 text

sourcekitd › SourceKitService › XPC › Xcode send request › sourcekitd response

Slide 27

Slide 27 text

SourceKit C API › SourceKit provides a set of APIs that you can write your program to call SourceKit. › There are some 3rd open source softwares help you communicate with SourceKit, such as SourceKitten.

Slide 28

Slide 28 text

Use SourceKit for parsing 📃 📋 💻 🔬 Source Code Parsed Result SourceKit Parsing Program XPC

Slide 29

Slide 29 text

Example Source Code

Slide 30

Slide 30 text

Example Parsing Result

Slide 31

Slide 31 text

Find Declarations There is a public declaration of structure called MilkTea Declaration Name Type Accessibility

Slide 32

Slide 32 text

Find References Inside MilkTea, there is a public declaration of variable sugar which is a SugarAmount Reference to another type Type Name

Slide 33

Slide 33 text

Build Dependency MilkTea SugarAmount IceAmount Double sugar volume ice init()

Slide 34

Slide 34 text

Build Dependency (Simplified) MilkTea SugarAmount IceAmount Double

Slide 35

Slide 35 text

Build Dependency Graph Module A

Slide 36

Slide 36 text

Build Dependency Graph across Modules Module A Module B

Slide 37

Slide 37 text

Traverse Dependency Graph Module A Module B

Slide 38

Slide 38 text

Find Unreached Nodes Module A Module B

Slide 39

Slide 39 text

Unreferenced Declaration › They are not in use because they are not reached › We could consider to remove them from source code › Unreached nodes are unreferenced declaration

Slide 40

Slide 40 text

Practice in LINE Internal Modules Applied on 3 Binary size Reduced 44% For LINE app Saved 2.1MB

Slide 41

Slide 41 text

Recap › To find out redundant code, we can use language tool such as SourceKit to analyze source code and build dependency graph. › Remove redundant code reduces app binary size. › Link Map helps us have a better understanding of binary size for each components and source files.

Slide 42

Slide 42 text

Thank you