Slimming App packages is to reduce the size of App packages and save App download traffic. If you download an App from the App Store and it’s over 150MB, you have to download or update it on a Wi-Fi environment, so if it’s over 150MB, you may lose most of your users indirectly. If our App is compatible with iOS7 and iOS 8, Apple has officially stated that the size of the main binary text segment cannot exceed 60MB. If the size exceeds this standard, we cannot submit to App Strore for approval.
The following table lists the package sizes of some commonly used apps at home and abroad.
APP | version | The size of the |
---|---|---|
Alipay | 10.1.60 | 167.5 M |
taobao | 8.6.10 | 207.6 M |
7.0.3 | 230M | |
drops | 5.2.45 | 202.4 M |
trill | 5.7.0 | 170.2 M |
Sina weibo | 9.3.1 | 191.5 M |
Netease Cloud Music | 6.1.0 | 147.7 M |
216.0 | 256.5 M | |
7.47 | 110.9 M | |
88.0 | 90.2 M |
It can be seen from the above table that currently only netease Cloud Music,Instagram and Twitter have packages less than 150M. So what can developers do to optimize the size of their App packages?
1. App Futures provided by Apple
We know that different devices have different screen sizes, resolutions, CPUS, Gpus, hard disk sizes, etc. In response to this, Apple has officially provided developers with App Stochastic technology, which provides current-device-only packages for users to download for different devices. For example, the iPhone 5C will only download libraries for 32-bit running chips and 2x image resources, while the iPhone 8P will download libraries for 64-bit chips and 3X image resources.
See App Framework in Xcode video App Hillclimbing official Documentation for Kinematic documentation
(1),App Thinning
There are three ways:App Slicing
.Bitcode
,On-Demand Resources
App Slicing
: iOS9 after apple official out of the solution, in toiTunes Connect
uploadApp
Package, rightApp
Do the cutting process, create different variant packages, so that they can be applied to different devices;Bitcode
: is also apple’s solution after iOS9 to optimize the package size for specific devices.On-Demand Resources
: Mainly for the situation of multi-level service,On-Demand Resources
Resources for subsequent levels will be downloaded according to the user’s level download progress, and the resources that have passed will be eliminated, which can reduce the initialApp
Package size.
(2) Then how to apply in the projectApp Thinning
?
(2.1),Slicing
The use of
With App Slicing, most of the work is done by Xcode and the App Store, and the developers themselves don’t have to do anything. In development, just create the Xcassets directory and add images to it. Xcode creates a directory called assets. xcassets by default when creating a project. You can add images to it during development.
You can also create a New project Catalog by selecting New File >Resources >Asset Catalog.
When we use Xcassets, we add corresponding 2x resolution and 3X resolution pictures, which will be created into different installation packages after uploading to the App Store to reduce the size of the App installation package. At the same time, Apple will automatically add the chip instruction set architecture file required by the current device to the installation package.
(2.2),Bitcode
use
Apple Bitcode official documentation
What is bitcode?
Typically, after iOS9, when you create a new project, Xcode will default to bitcode. Intermediate Representation layer (IR) in LLVM, which is between source code and machine code, is generated by clang at the front end of the compiler, optimized by LLVM optimizer, and then delivered to the back end to generate corresponding CPU instructions.
Bitcode is provided to Apple, which can re-optimize the code for the CPUS of various models (including new ones). This will not increase the size of the package itself, and the uploaded binaries will become larger, but it will not affect the user’s download size.
If bitcode is enabled, accordingly, all pods in use must have Bitcode enabled. Bitcode must be complete, otherwise it will be invalid and an error will be reported during compilation.
After the bitcode option is enabled, bitcode is not entered in debug mode, only in Archive mode.
(2.3),On-Demand Resources
The use of
On-demand Resources official documentation
Images, audio and other resource files are separated, and resources are classified by ResourceTag in the development stage and stored on Apple’s server. The App initiates requests as needed, and the operating system manages downloads and storage, generally used for game resources or in-app purchases.
Advantages:
- The package size is smaller, saving more storage controls for the device
- (Game -> Level -> Download current Resources)
- Rarely used resources can be placed on a server (Tutorial)
Disadvantages:
- Resources need to be downloaded from Apple servers
- Resources need to be classified by tag and corresponding configuration policies need to be formulated
- Managing when to download and when to release in code adds complexity to resource management
2, delete abolished, useless resources
In the iteration of the App, we are constantly adding new resources. However, due to the later changes in requirements, design and interaction, some resources added in the early stage became useless, but these resources were not deleted at that time, resulting in our resources becoming more and more bloated, and the App package becoming bigger and bigger. For example, we added the Materials of the Christmas version to our App, but after this version, these materials are useless. Deleting these useless resources is also the simplest and most effective operation that can bring the most obvious effect to the size of App package. Then, how to find and delete these useless resources?
- (1) Before arraignment, use the simplest method, through
Xcode
theFind
Function in the code to search the name of the image resource, if not found, it means that there is no use of the image, directly delete the image resource can be. But this is more troublesome, and the efficiency is lower; - (2), through
Mac
terminalFind
Command to search for all image resources in the project and delete the unnecessary image resources. You can use the image resources provided by the systemNSFileManger
Class to delete; - (3) Here is a recommended open source tool for youLSUnusedResources.
LSUnusedResources
Not only haveGUI
And it’s easy to add and delete. - (4) Delete some other files, such as those used in our projectlottieAnimation, so there will be some local equivalents
json
Files, for the annulled files, can be deleted through the above method;
3. Image resource compression processing
Just think, if the designer to picture is very large, an image to a few KB, and even a few MB, if such a lot of resources, so the final package installation package very naturally, as in our project designer gives a picture of a full screen background only 1 x to reach 53 KB, so to image compression processing is urgent.
The goal is to compress the image as much as possible without losing quality, which will save some space and reduce the size of the installation package. Google’s solution for converting images to WebP(which requires a ladder to open) is recommended.
(1) Why use itWebP
WebP
High compression rate, the naked eye basically can not see the difference, support lossy and lossless mode, after compression not only does not lose the picture quality, the official proposed relative to our commonly usedPNG
Format reduces size by 26%.WebP
supportAlpha
Transparent and24-bit
The number of colors, it doesn’t look likePNG8
So because the color is not enough to appear burrs;WebP
Compatible with current mainstream browsers and platforms;
(2),WebP
The installation of
Use the Homebrew command to install webp, enter:
brew install webp
Copy the code
If I want to convert the all_background. PNG image into WebP with lossless compression, I can use the following command:
cwebp -lossless all_background.png -o all_background.webp
Copy the code
After compression, only 3K memory, the optimization effect is very obvious.
(3),WebP
The use of
WebP image loading can refer to :WebP decoding support (Objc & Swift)
let path : String = Bundle.main.path(forResource: "all_background", ofType: "webp")! ; self.backgroundImg.image = UIImage.init(webPPath: path);Copy the code
For more information about how to use WebP, please refer to the official WebP website.
4, delete the abolished code file
In the continuous update and iteration of the product, it is inevitable that some functions will be deleted or abolished in the code. However, as a developer, sometimes the abolished code is not deleted in time. In this way, as the number of codes increases, there will be more and more redundant or invalid codes in the APP. The purpose of our code slimming is to find these codes and delete them. So what can be done to achieve this goal?
(1) Use Xcode Analyze static analysis
To open Xcode, Product –> Analyze, or use the command to ⌘ + ⇧ + B shortcut.
Xcode’s Analyze static analysis not only finds uncalled code, but also finds:
- Wild pointer or uninitialized variable in code
- Memory leak code
- No used libraries or frameworks
When I use Xcode static analysis, I find that there are still many problems, such as the effect of invalid file or class check is not very ideal, so I recommend AppCode to do static analysis.
(2) Use AppCode for static analysis
Static analysis can be done directly with AppCode. It is also easy to go to AppCode –>code– >Inspect code;
After static analysis is completed, Unused code can be seen in the Unused code, as shown in the following figure:
Unused class
Is abandoned classUnused import statement
Is a garbage class reference declarationUnused property
Is a useless propertyUnused method
Is a useless methodUnused parameter
Is a useless parameterUnused instance variable
Is a useless instance variableUnused local variable
Is a useless local variableUnused value
Is a useless valueUnused macro
Is a useless macro definitionUnused global decaration
Is a useless global declaration
So the question is, will static analysis with AppCode check out all the deprecated code? No, here are several cases where AppCode thinks a method or class is not called:
- When using
objc_msgSend
or@selector
When a method is called - When attributes are used using points
- When a parent class declares a method implemented in a subclass
- use
NSClassFromString
Classes declared in runtime mode
UIViewController *TestVC = [[NSClassFromString(@"TestClassViewController") alloc]init];
SEL aSelector = NSSelectorFromString(@"setIsPlayLaunchAnimation:");
if ([TestVC respondsToSelector:aSelector]) {
IMP aIMP = [SearchMainView methodForSelector:aSelector];
void (*setter)(id, SEL, BOOL) = (void(*)(id, SEL, BOOL))aIMP;
setter(TestVC, aSelector,true);
}
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:TestVC];
Copy the code
Therefore, using tool static analysis is not a perfect way to find all discarded code. Manually verify that the method or class is called before deleting the code. The easiest way to do this is to take advantage of Xcode’s built-in Find functionality.
(3) Delete the project of pheasant open source code
There are many excellent peers who share the codes written by themselves, which makes some programmers, when they meet a requirement in development, first think of going to GitHub, CSDN and Code4App to find demo, rather than build the engine according to the requirement, find a relatively similar code, modify it and directly add it to their own code. But this can create a lot of uncontrollable problems. Such as:
- Late requirement change
- Compatibility problems after system version upgrade
- Bugs appear to the author
Issues
Can’t get a response or resolution in time - The code author does not maintain for a long time
I personally suggest that we should be careful when using open source code from a third party. We should not randomly find an open source code and add it to our own projects. We can learn from the author’s ideas and build wheels by ourselves. Also, the best code on GitHub is mostly system API encapsulation, such as:
Alamofire, AFNetWorking
Is theURLSession
Further encapsulation of,SnapKit, Masonry
Is theAutoLayout
The encapsulation,
Of course, there are some features or apis that Apple doesn’t provide to developers, so we have to use third-party open source code, such as
- Before iOS 6, Apple didn’t offer it
UICollectionView
So developers can only use open source code from third parties, - Apple didn’t offer iOS 7 before
UITableViewCell
Adaptive height, so we can only useUITableView+FDTemplateLayoutCell
Personal advice: If there is an API provided by the system, use the system method or API first.
In the latest project of our development team, we did not use SnapKit, but NSLayoutAnchor provided by Apple. Personally, I think Apple can basically meet the needs of most not too complicated apps after continuous optimization from iOS 9.
This article mainly introduces how to slim down App from image resources and code in iOS development. If you have better and better solutions, welcome to comment.
Links:
Xcode Help What is app thinning? (iOS, tvOS, watchOS)
Apple Developer App Thinning in Xcode
Package size: How can you slim it down in terms of resources and code?
Mad Mark’s Blog: iOS Apps slim down
Bytedance technical team: iPhone package optimization
Toutiao iOS installation package size optimization – Ideas and practice