“This article has participated in the good article summoning order activity, click to view: back end, big front double track submission, 20,000 yuan prize pool for you to challenge”
preface
Hi Coder, this is CoderStar!
IOS optimization will be a topic that will include package size optimization (slimming down), startup time optimization, UI optimization, and more. So let’s start with slimming.
APP size is divided into two concepts: APP download size and APP installation size.
- Download size refers to the space taken up by the App’s compressed package (i.e., the.ipa file). Users download the compressed package when downloading the App to save traffic.
- When the compressed package is downloaded, it will be automatically decompressed, decompression process is usually called the installation process; The installation size refers to the space occupied by the decompressed package.
The size the user sees in the store is the installation size. If you want to see the download and installation size of the installation package on each model, you can view it in the App Store Connect background.
App Store OTA download size limits:
Although Apple has changed App download sizes over the years, from 100 megabytes to 150 megabytes to 200 megabytes now. Now, when an App download exceeds 200 MB, two things happen:
- Users below iOS 13 will not be able to download the App through cellular data.
- For iOS 13 and above, you need to manually set it to download the App over a cellular network.
Apple __TEXT segment size limit:
- Before iOS 7, the sum of all __TEXT segments in a binary file could not exceed 80 MB;
- For iOS 7.X to iOS 8.X, in binaries, the __TEXT segment in each particular schema must not exceed 60 MB;
- After iOS 9.0, the sum of all __TEXT segments in a binary must not exceed 500 MB.
By the way, why did Apple change the download size limit from 100 megabytes to 150 megabytes? The main reason is that when Uber used Swift to reconstruct and develop the APP, with the growth of its business, it found that it could no longer reduce the APP size below 100M, so it had to contact Apple to ask it to increase the download size to 150M. Apple’s Swift team also helped add some compiler options (-osize).
This article focuses on how to reduce the download size of your APP, because it’s a long article, so if you don’t want to read it closely, you can skip the details and go to the conclusion of each section.
Thin body direction
Change the suffix of the IPA installation package to zip, decompress it, and display the contents of the. App package. You can see the components of the installation package directly. It usually includes the following sections:
- Exectutable: Mach-o executable file
- Resources: Resource files
- Image resources: Assets. The car/bundle/PNG, JPG, etc
- Video/audio resources: MP4 / MP3, etc
- Static web resources: HTML/CSS/JS, etc
- View resources: XIB /storyboard, etc
- Internationalization resource: xxx.lproj
- Others: text/font/certificate, etc
- Framework: A dynamic library used in a project
- SwiftSupport: libSwiftxxx and a series of Swift libraries
- Other dependencies: Embeded Framework
- Pulgins: Application Extensions
- Appex: Its composition is roughly consistent with that of the IPA package
The core component is the resource file and the Mach-o executable, which is where the bulk of our work is going. In the process of slimming, you should try to use the best optimization method with the highest ROI to pay less energy and get more benefits.
Before we get into the direction of optimization as developers, let’s take a look at Apple’s own optimization mechanisms for APP download size, and take full advantage of them.
App Stack Optimization
App Stack refers to an optimization introduced after iOS9, in which Apple automatically reduces the size of apps that need to be downloaded for distribution to specific users, as much as possible. It mainly contains the following three functions.
Slicing(application segmentation)
After the. Ipa is uploaded to App Store Connect, during the building process of App Store Connect, the App is automatically split and content (mainly architecture and resources) applicable to the current device is selected for download. The differences are mainly in terms of architecture (32-bit versus 64-bit) and resources (@1x, @2X versus @3X).
The architecture aspect is not controlled by the developer, but the resource aspect requires the image to be managed in the Asset Catalog. If it is placed directly in the Bundle, it will not be optimized.
Related knowledge points and optimization conclusions of Asset Catalog can be seen in the Assets Catalog section below.
Summary: Try to hand over pictures and other resourcesAsset Catalog
Management.
Bitcode
Bitcode is an intermediate representation (IR) of a compiled program. Apps that contain Bitcode uploaded to App Store Connect will be linked and compiled in the App Store. Apple refines binary apps that contain Bitcode without submitting a new version of the app to the App Store. It’s an internal Apple optimization, but it needs to be noted;
- Support all of them. The static libraries we rely on, the dynamic libraries, and the third-party libraries managed by Cocoapods all require Bitcode to be turned on. Otherwise, the package will fail to compile and the error will be indicated in Xcode.
- Crash positioning. After Bitcode is enabled, the final generated executable file is automatically generated by Apple, and a new symbol table file will be generated at the same time. Therefore, we cannot use the DYSM symbolic file generated by our own package for symbolization, but use the DYSM symbolic file generated by Apple.
- Flutter does not support Bitcode, and if the project contains the Flutter framework, you will not be able to use this method;
- BitCode is optional for iOS development, mandatory for watchOS development, and not supported on Mac OS.
To Enable this function, run Build Settings -> Enable Bitcode -> Set this parameter to YES.
If you want to learn more about Bitcode, check out my previous post on iOS Compilation In Brief.
Conclusion: It can be decided according to the actual situation of the project. Do not enable the project if the project has a mix of Flutter, depends on part of the library does not support Bitcode, and do not want to deal with DYSM symbolization, otherwise you can choose to enable it.
On Demand Resources
On-demand Resource is where a collection of images can be placed On Apple’s servers, not downloaded with the App, and not downloaded until the user actually enters a page.
Application scenarios: Stickers or filters for camera applications, level games, etc.
To Enable this function, run Build Settings -> Enable On Demand Resources -> Set this function to YES (enabled by default).
Set the Tag type of the resource. The types include:
- Initial Install tags: Download resources and apps at the same time. In the App Store, the App size calculation already includes these resources. When no NSBundleResourceRequest object accesses them, they are purged from the device.
- Prefetch Tag Order: Download the App after it is installed. Download the App in the order listed in the preload list.
- Dowloaded only on demand: It is downloaded only when requested in the App.
If Demand Resources are present in the project, the resulting installation package structure is roughly hierarchical:
- The project name. The app
- OnDemandResources folder
The specific use method is not expanded here.
We do not download the resources in the OnDemandResources folder when downloading the installation package, in order to reduce the size of the download installation package.
Conclusion: This method is the same as the nature of resource remoting mentioned below, except that one is placed on its own server and the other on Apple server. You can choose whether to use it according to the actual situation of your project.
Resource File slimming
There are many optimization directions for resource files, and the risk is relatively small compared with optimizing Mach-O executable files.
Remove useless/duplicate resources
In the iterative development of business, it is quite normal to have useless picture resources. We can find out which picture resources have not been used with the help of tools. The following two tools are recommended:
- LSUnusedResources: Visual client tool;
- FengNiao: Command line tool that can be embedded in a Run Script or used in a CI system and supports more powerful pattern matching.
Because the principle of these tools is to use regular expressions in related files (.m,.swift, etc.) to detect whether there is a character of the image name, the following problems exist. Problem:
- If the icon name used in the code is a patchwork, it will be mistaken for a discarded image;
Duplicate Photos can be used to detect Duplicate/similar images from the content.
By extension:
The reason for using automated tools to detect duplicate resources is because resources are weakly typed and it is a cumbersome process to maintain manually during project iterations. By switching your thinking, if the resource is strongly typed, it’s fairly easy to maintain. There is currently a tool called R.swift that makes resources strongly typed in a sense, similar to R files in Android development.
You can use Fdupes to find duplicate files in a project. The principle is to compare the signatures of different files, and the files with the same signature will be judged as duplicate resources.
You can use the fduPes-sr folder name to view the size of duplicate files in all the directories and subdirectories involved, and the rest of the relevant instructions can be viewed by yourself. It is not recommended to use the fdupes command to directly delete the duplicate resources. It is risky.
Conclusion: Considering the inaccuracy of the tool, we can use the tool to check which resources are not used, and then delete them after manual confirmation. For resources that cannot be detected by the tool, screening can only be done manually, and each person can be assigned several modules to improve efficiency.
Resources compression
Note: The resources here do not include those managed by the Assets Catalog.
PNG resource
This part involves a lot of antecedents and consequences, in order to ensure that you can understand, will first foreshadow some basic knowledge, please read patiently.
Xcode’s Build Setting gives us two compilation options to help compress PNG resources.
Remove Text Medadata From PNG Files (default) : Helps Remove Text characters From PNG resources such as image name, author, copyright, date of creation, comments, etc. Compress PNG Files (open by default) : When set to YES, all PNG images in the project will be automatically lossless compressed and formatted using the open source pngCrush tool.
Compress PNG Files set to YES XCode will call the script for that path / Applications/Xcode. App/Contents/Developer/Platforms/iPhoneOS platform/Developer/usr/bin/iPhoneOS – optimize.
The pngCrush tool is located in its sibling directory, and the iPhone OS-optimize script contains the following:
sub optimizePNGs {
my $name = $File::Find::name;
if ( -f $name && $name =~ /^(.*)\.png$/i) {
my $crushedname = "$1-pngcrush.png";
// $PNGCRUSH is the PNGCRUSH tool path
my @args = ( $PNGCRUSH, "-q"."-iphone"."-f"."0" );
if ( $stripPNGText ) {
push ( @args, "-rem"."text" );
}
push ( @args, $name, $crushedname );
if(system(@args) ! =0) {
print STDERR "$SCRIPT_NAME: Unable to convert $name to an optimized png! \n";
return;
}
unlink $name or die "Unable to delete original file: $name";
rename($crushedname, $name) or die "Unable to rename $crushedname to $name";
print "$SCRIPT_NAME: Optimized PNG: $name\n"; }}Copy the code
In terms of content, the script uses the PNG suffix to determine whether the image is a PNG image, and if the suffix changes, the image will not be processed by the PngCrush tool.
We can manually use the PngCrush tool with the following command.
#PNG is encoded to generate image1.png
xcrun -sdk iphoneos pngcrush -iphone -f 0 image.png image1.png
#PNG is decoded and restored to image1.png
#Even if it is restored to the original image, it will not be exactly the same, so I will not expand the description here
xcrun -sdk iphoneos pngcrush -revert-iphone-optimizations image.png image1.png
Copy the code
The main changes in pNGCrush coding results are as follows:
- CgBI blocks are inserted before IHDR blocks to represent this format
- Modify the data in the IDAT block to remove the Zlib compression header and adler-32 checksum.
- 8-bit true color images are stored in BGR/BGRA order, rather than RGB and RGBA order as indicated in the IHDR block;
- Image pixels use pre-multiplied alpha;
- The modified file is used. PNG defines file extensions and internal file structures for valid images, but PNG compliant viewing and editing software can no longer handle them;
- Added an iDot data block, which is Apple’s custom data block.
Essentially, it turns a normal PNG image into an optimized CgBI format. Pngcheck can be used to view the image information before processing, and pngdefry can be used to view the image information after processing (it can also restore the CgBI format PNG, which is similar to the decoding function of pNGCrush tool).
From the above changes, the pngCrush tool coding process is not a simple compression of data, more important is the file format changes. Because in iPhone, images are processed in memory in BGRA format, so the modified format becomes a more convenient format for iPhone to process and speed up processing.
According to the compression effect tested by myself, the size of the PNG image placed in the Bundle increases instead of decreasing after processing by PNGCrush. So far, no specific factors have been found to affect the compression effect.
Conclusion: Compress PNG Files is used to Compress PNG images, but its main purpose is not to Compress the image size, but to convert PNG into a format that is easier for iOS to process and faster to recognize. You can choose or choose according to the package size of the project when it is opened or closed.
The PNG resource
There are two ways to compress non-PNG resources:
- Directly through some compression tools will be compressed resources, the format remains the same, such as some image resources, audio and video resources, image compression tools will be described below.
- Some text resources, such as JSON files and HTML files, cannot be compressed by the above methods. Instead, they can be compressed into ZIP and other compression formats, which can be divided into three steps:
- Compress Phase: Add scripts in Build Phase. Zip the text files in the whitelist during Build Phase.
- Decompression stage: In the App startup stage, the decompression operation is carried out in the asynchronous thread, and the decompressed products are stored in the sandbox;
- Read phase: when the App is running, hook reads these files and changes the read path from the Bundle to the corresponding path in the sandbox;
Conclusion: Appropriate compression tools can be selected to compress the image resources managed by audio and video and non-assets Catalog. A second runtime decompression is available for larger text files, such as Lottie animation’s JSON file.
Assets Catalog
There are a lot of technical points involved in the Assets Catalog, and a separate blog post may be devoted to this part in the future.
Remove @1x image
@1x for iPhone 3Gs, @2x for iPhone 4, 3x for iPhone 6p.
Conclusion: You can delete all @1x image resources in Assets.
Image compression
The Assets. Car file is the build product of the Asset Catalog in the project. During the construction of Xcode, when the asset catalog node is compile, the tool actool that builds asset catalog will first decode the PNG image in the Asset catalog to get Bitmap data. Then the encoding compression algorithm of Actool is used to process the encoding compression.
If you put JPG files in Assets during development, they will also be PNG images in the resulting asassets. Car file.
Xcrun assetutil — Info Assets. Car. You can use this command to check the encoding compression algorithm used for each image in assets. car.
The current compression algorithms used by AcTool include lzfse, palette_img, deepmap2, deepmap_lzfse, zip, Factors influencing which algorithm to use include iOS version, ASSETCATALOG_COMPILER_OPTIMIZATION Setting (in Build Setting), etc.
- IOS 11.x: The corresponding compression algorithm is LZfse and zip.
- IOS 12.0.x – iOS 12.4.x: The corresponding compression algorithms are deepmap_lzfse and palette_img;
- IOS 13.x: The corresponding compression algorithm is deepmap2;
Lzfse < palette_img ~= deepmap_lzfse < deepmap2
If ASSETCATALOG_COMPILER_OPTIMIZATION is set to space then on earlier versions of iOS, images that use the LZFSE compression algorithm will become zip, It can reduce the image usage of iOS 11. X and lower devices. Other iOS compression algorithms are not affected by this configuration.
-
Lossless compression reduces the size by changing the image’s encoding compression algorithm, but does not change the Bitmap data. For Actool, the input it receives (the Bitmap data) does not change, so lossless compression does not optimize the size of Assets.car. But it can be used to optimize non-asset Catalog managed images.
-
Using lossy compression and appropriate compression methods can reduce the size of assets. car. Images can be coded using the RGB with palette to achieve the image compression effect. This type of coding is especially suitable for ICONS with relatively close internal colors. However, it is important to note that if the image has a translucent effect, this compression method may cause noise in the translucent area, so please check carefully after compression.
The resulting byte stream encoded in RGB with Palette first maintains an array of colors. Each member of the color array maintains a color using RGBA’s four components. Each pixel in the image stores a color array with a subscript that represents the color of that point. The type and quantity of color array maintenance are determined by the image, and you can manually limit the type of color array maintenance, the default value is 256, see the related link at the bottom of the Palette Images for details.
Using the imageoptim-CLI tool described below, you can change the image to RGB with Palette, using the following command:
imageoptim -Q --no-imageoptim --imagealpha --number-of-colors 16 --quality 40-80 ./1.png
–number-of-colors: controls the number of colors maintained in the color array; –quality: control the image quality to the original percentage; The values in the command can significantly reduce the packet size while maintaining an invisible mass change.
Take image resources as an example, we can use tools to compress them. Several recommended tools are as follows:
- TinyPng: Web tool for lossy compression;
- TinyPNG4Mac: TinyPng client tool that does not require Internet connection to use a browser.
- ImageOptim: A client-side tool that supports lossless and lossy compression. You can customize the compression method.
- ImageOptim-CLI: Mac is available
brew install imageoptim-cli
Install, it will be called optionally according to your specificationJPEGmini
,ImageAlpha
,ImageOptim
And other tools to realize the automation of the intermediate process.
If you want to extract the PNG from the CAR file, you can use Asset Catalog Tinkerer.
By extension, a good tool is to develop a sharp tool, before finishing up some good Mac efficiency tools, Mac efficiency software
Conclusion: Use Asset Catalogs to manage resources that can be managed by Asset Catalogs. Do not use lossless compression on your images, which will not result in compression. If you want to compress, use the lossy compression method mentioned above and check the result.
Image resources use Webp format
Google’s open source format, Webp compression rate is relatively high, and supports both lossless and lossless compression modes, resulting in a smaller image volume, and the difference is not visible to the naked eye. According to Google’s tests, lossless compression of WebP images reduces the volume of a PNG file by 26%, and lossy compression of WebP images reduces the volume of a JPEG image by 25% to 34% compared to the equivalent quality metric.
However, compared with JPG and PNG, WebP has a lower CPU consumption and decoding time in codec, because encoding is a one-time operation when users upload pictures, and the encoding process is carried out in the background of the server, which has little impact on users, and the main impact on users is the decoding process. This will cause the image to load more slowly. Therefore, we need to make trade-offs between performance and volume according to the actual situation of the project.
From the perspective of server bandwidth and traffic, the bandwidth and cost will be reduced due to the smaller size of the picture.
Two ways to switch to WebP format are recommended
- ISpart: Produced by Tencent, GUI tool;
- Webp toolsOn Mac, you can install WebP tools using Homebrew
brew install webp
;
IOS native does not support WebP format loading, you need to introduce SDWebImage/WebP, or self-developed.
Conclusion: This scheme is suitable for the whole big front-end and back-end unified adjustment, overall optimization, if a single client adjustment, may not reach the optimal effect.
Resource dynamic
In addition to using on-demand Resources to put some of our Resources On Apple servers, we can also move some of our local Resources to our own servers. This not only reduces the installation package size, but also makes these resources dynamic. Resources suitable for the server should contain the following features:
- Does not affect the first screen loading experience;
- The change frequency is high;
- Large in size;
Such as some Banner ads, theme resources, audio and video resources, H5 resources.
Bottom line: Try to place resources that meet the above characteristics on the server.
Icon to optimize
- Use Tint Color to simplify monochrome ICONS;
- Use IconFont instead of monochrome ICONS.
- Integrate some similar ICONS;
Conclusion: If the project has relative design specifications and standard icon styles, using icon fonts is a good solution. The remaining optimization points should be used according to the actual situation of the project.
Improved compilation options
Xcode supports several optimizations at the compiler level. By modifying the configuration of the Build Setting, you can choose between a faster Build speed and a smaller binary size and faster execution. Some of these optimizations affect resource files. Some will affect the executable file, because the content is more, so a separate chapter description.
The cost performance of this method is very high. Changing a configuration may bring benefits, but it may have certain risks, which requires caution.
Some of the Xcode default configurations mentioned below may not be the default configurations on earlier versions of Xcode. If not, you can manually select them.
Get rid of useless architecture
You can set Excluded Architectures in the Build Setting – Excluded Architectures.
Let’s take a look at some of the architecture implications:
- Simulator 32-bit processor testing required
i386
Architecture; - Simulator 64-bit processor testing required
x86_64
Architecture; - A real 32-bit processor
armv7
Or,armv7s
Architecture; - Real machine 64-bit processor needs
arm64
Architecture.
armv6 | armv7 | armv7s | arm64 |
---|---|---|---|
iPhone iPhone2 iPhone3G The first and second generation iPod Touch |
iPhone4 iPhone4S IPad1 -iPad3, 3, 4 generation iPod Touch iPad mini |
iPhone5 iPhone5C iPad4 |
IPhone 5S and all other models |
Conclusion: The ARM64 architecture is theoretically sufficient and can be removedarmv6
、 armv7
、 armv7s
Three architectures.
LTO(Link-Time Optimization)
You can set the Optimization mode under Build setting-link-time Optimization
It offers three options:
No
Do not enable link period optimization; (Default)Monolithic
Generate a single LTO file, regenerate each link, no cache high memory consumption, parameter LLVM_LTO=YES;Incremental
Generate multiple LTO files, incremental generation, low memory consumption, parameter LLVM_LTO=YES_THIN;
The optimization that LTO can bring is:
- Inlining some functions: no need to press the stack before calling the function, no need to call the function out of the stack operation, improve the running efficiency and the utilization of the stack space;
- Get rid of some useless code: If a piece of code is distributed in multiple files but is never used, the normal -O3 optimization method cannot find redundant code across intermediate code files and is therefore a local optimization. but
Link-Time Optimization
Technology can find redundant code across intermediate code files at link time; - Global optimization of the program: this is a relatively broad concept. For example, if a branch of an if method is never likely to be executed, then there should be no code for the branch in the resulting binary.
The LTO will slow down the compile link, so it is recommended to open it when the official package is opened. After LTO is enabled, the readability of the Link Map is significantly reduced and there are many more classes starting with numbers (due to the global optimization of LTO). Therefore, if you need to read the Link Map, you can disable LTO first.
Although LTO is a link-time optimization, it is still required to participate in compile time. A compiled with LTO is essentially LLVM BitCode. If it is built without LTO, it is directly machine code. LTO optimization is not possible with direct links.
After LTO is enabled, repeated code across compilation units is linked by the linker generating a separate.lto. O object file. In particular, some of the structures required by Objc Runtime, such as literal strings for method signatures and protocol structures, have been significantly optimized. Turning on both Oz and LTO allows the function to have only one copy of the installed package to maximize the size of the installed package. It is recommended to enable this option if the project uses Protocol heavily.
Conclusion: Can beLink-Time Optimization
Option byNO
Instead ofIncremental
。
Language compilation optimization
OC
OC’s parameters for compiling inline optimizations are in Build Settings -> Apple Clang-code Generation -> Optimization Level.
- None[-o0]: The compiler does not optimize the code, meaning faster compilation and more debugging information. This is enabled in Debug mode by default.
- Fast[-o, O1]: The compiler optimizes code performance and minimizes compile time. This option uses more memory when compiling.
- Faster[-O2] : The compiler turns on all optimization options that do not depend on the space/time tradeoff. Here, the compiler does not unroll loops or inline functions. This option increases compilation time and code execution efficiency.
- Fastest[-O3] : The compiler enables all optimization options to improve code execution efficiency. In this mode, the compiler performs function inlining so that the generated executable file becomes larger. This mode is generally not recommended;
- Fastest [-os] : the compiler will enable all optimization options except one that significantly increases the package size. It is enabled in Release mode by default;
- Fastest, Aggressive Optimization[-ofast] : Enabling all optimizations in -O3 may enable Optimization options that violate language standards. This mode is generally not recommended.
Conclusion: Use the default configuration.
Swift
The Swift Compiler inline Optimization parameters are located in Build Settings -> Swift Compiler-Code Generation -> Optimization Level. Optional parameters are as follows.
- No optimization[-onone] : No optimization[-onone] : No optimization to ensure faster compilation. It is enabled in Debug mode by default.
- Optimize for Speed[-o] : The compiler will Optimize for Speed, increasing the package size to some extent. It is enabled in Release mode by default;
- Optimize for Size[-osize] : The compiler will minimize the package Size and minimize the code execution efficiency.
The core principle of Optimize for Size is to reuse functions that correlate repeated continuous machine instructions, as opposed to function inlining. Thus, turning it on can reduce the size of the binary, but at the same time it theoretically incurs an additional cost in execution efficiency that needs to be evaluated for performance (CPU) sensitive code usage.
For the official description, see Code Size Optimization Mode in Swift 4.1
It is also used with the Compliation Mode setting, which has two options
- Single File optimization can reduce incremental compilation time, and can take full advantage of the multi-core CPU, optimize multiple files in parallel, improve compilation speed. But you can’t do anything about cross-references;
- Whole Module: Optimizes the Whole Module to the maximum extent that it can handle cross-references. Disadvantages can not take advantage of multi-core CPU, every compile will recompile the entire Module;
In Relese mode, it works best when -osize and Whole Module are turned on at the same time. In existing cases, it reduces executable size by 5% to 30% and has a minimal performance impact (about 5%).
Conclusion: Change the default Release configuration toOptimize for Size[-Osize]
.Compliation Mode
Option toWhole Module
Dead code clipping
This can be set in the Build Setting – DEAD_CODE_STRIP item.
Static language code such as C or C++ will be marked Dead if it is not used after the build. Enable DEAD_CODE_STRIP = YES and these Dead codes will not be packaged into the installation package. In LinkMap these symbols are also marked as <
>.
This item also belongs to cleaning up useless code.
Conclusion: The default configuration is YES. Therefore, you do not need to change the default configuration.
Remove symbol information
Symbols in an executable file refer to all the variables, classes, functions, enumerations, variables and address mapping relationships in the program, as well as some debugging symbols used to locate code in the source code. Symbols are important for breakpoint positioning and stack symbolization.
Strip Style
Strip Style represents an option for the type of symbol we want to remove. It is divided into three options:
- All Symbols: Removes All Symbols, usually enabled in the main project;
- Non-global Symbols: Remove non-global Symbols (retain Global Symbols, Debug Symbols are also removed), not Symbols that are redirected when linking. This option is recommended for static/dynamic Symbols.
- Debug Symbols: Removes the Debug symbol, which prevents breakpoint debugging.
Conclusion: Main project selectionAll Symbols
, static and dynamic library selectionNon-Global Symbols
.
Strip Linked Product
Not all symbols are required, such as Debug Map, so Xcode provides us with Strip Linked Product to remove unnecessary symbol information (symbols corresponding to the options selected in the Strip Style). After removing the symbolic Information, we can only use dSYM for symbolization, so we need to change the Debug Information Format to DWARF with dSYM file.
Note that the Strip Linked Product option only takes effect when Deployment Postprocessing is set to YES, while Deployment Postprocessing in Archive is not affected by manual setting. Will be forced to YES.
Conclusion:Deployment Postprocessing
Set this parameter to NOStrip Linked Product
Set toYES
That will beRelease
Under the modeDebug Information Format
Modified toDWARF with dSYM file
.
Strip Debug Symbols During Copy
Similar to Strip Linked Product, but this removes Debug symbols for libraries, resources, or extensions that are copied into the project package. Again, use the Strip command. This option is not controlled by Deployment Postprocessing, so we only need to enable it in Release mode, otherwise we will not be able to debug breakpoints and symbol the third-party library.
Cocoapods manages dynamic libraries (USe_Framework!) The case is relatively special, Cocoapods in the dynamic library is to use their own implementation of the script Pods-xxx-frameworks. Sh to achieve copy, so will not go through the Xcode process, Of course, this is not affected by Strip Debug Symbols During Copy. Of course, Cocoapods is source management, so you only need to manually set the Strip Linked Product in the source Target to YES.
Conclusion:Strip Debug Symbols During Copy
inRelease
Mode is set toYES
In theDebug
Mode is set tofalse
.
Strip Swift Symbols
Enabling Strip Swift Symbols helps remove all Swift Symbols from the Target. This option is also enabled by default. This option appears when Xcode exports the Xcarchive package to an IPA file, not through Build Setting.
Conclusion: It is generally selected by default. If it is not selected, please manually select it.
The option setting method was optimized
Most projects are managed using Cocoapods, and the project file is reset with each Pod install or Pod update. So you need to hook pod Install to set the build options for each Target in Pods.
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
config.build_settings['STRIP_INSTALLED_PRODUCT'] = 'YES'
config.build_settings['SWIFT_COMPILATION_MODE'] = 'wholemodule'
if config.name == 'Debug'
config.build_settings['SWIFT_OPTIMIZATION_LEVEL'] = '-Onone'
config.build_settings['GCC_OPTIMIZATION_LEVEL'] = '0'
else
config.build_settings['SWIFT_OPTIMIZATION_LEVEL'] = '-Osize'
config.build_settings['GCC_OPTIMIZATION_LEVEL'] = 's'
end
end
end
end
Copy the code
Mach-o executable thin
When optimizing the Mach-O file, we can analyze the Link Map file to give us some data reference and help us analyze the composition of Mach-O file.
Link Map is a TXT file that can be generated when compiling a Link. It is generated to help programmers analyze package sizes. The Link Map records how much space each method occupies under the current binary architecture. By analyzing the Link Map, we can see how much installation package space each class and even each method takes up.
Turn on the Write Link Map File switch in the Build setting and Xcode will generate a Link Map File. The path of the generated Link Map file is as follows: ~ / Developer/Xcode/DerivedData/project/Build/Intermediates noindex/project. The Build/Debug – iphonesimulator/project. The Build/project – LinkMap – normal – x86_64.txt
If you read the Link Map file directly, it will be inefficient and not intuitive. We can use some tools to help us analyze it.
LinkMap Tool address
Clean up useless code
Look for useless code through AppCode
AppCode provides a very powerful static Code inspection tool. Inspect Code can be used to find many Code optimizations.
Source scanning based
Typically, string matches are performed against source files. For example, classify A * A, [A XXX], NSStringFromClass(“A”), objc_getClass(“A”), etc., as classes to use, @interface A: B as classes to define, and then calculate the difference set.
There is an implemented tool based on source scanning called FUI, which is implemented by finding all #import “A” and comparing all files.
Manually remove
- Obsolete code that has been offline, AB test code that has been offline;
- The Native function implemented by transferring to H5, Hybrid, or RN can be cleaned periodically.
- Refactor parts of the functionality to remove certain code.
Remove the same code from multiple executables
If the Extension program and the APP host depend on the same static library, the two executables will contain the same code. If the Extension program and the APP host depend on the same static library, the Extension program will contain the same code. Personally, I think there are two solutions:
- Considering that the Extension program has less functions than the host program, you can try to use native functions instead of accessing third-party libraries.
- If you want to access the same library, you can introduce the library as a dynamic library. Finally, the two executable files will dynamically link the same library, avoiding repeated code.
Conclusion: Select the solution according to the actual situation of the project.
More optimization
Pod
Use resource_bundles in conjunction with XCassets to integrate resource files in various plug-ins, because resources in resource_bundle can be optimized by Xcode during build time, whereas resources in Resource cannot. In addition, this form can put the resources of each POD in its own Bundle, which is more convenient to manage.
Conclusion: If a custom Pod contains resources, try to refer to them as resource_bundle.
The code quality
- Code reuse, prohibit mindless copy of code, shared code sink into the underlying components;
- Repeat the functionality of the framework using a set;
- Don’t introduce a framework for a small feature, or switch to a powerful but heavyweight framework when there are similar lightweight frameworks;
- .
Conclusion: This part needs to improve personal coding quality, team culture, team management and other aspects.
other
There are also some optimization methods, such as binary segment compression, __TEXT segment migration and other ways, you can go to look for relevant information, here is only a brief introduction to the relevant principles.
- Binary segment compression: Not every segment/section in a Mach-o file is used the first time the program starts. This segment/section in a Mach-o file can be compressed during the build process, and then simply decompress the segments into memory before they are used, achieving the effect of reducing the package size while keeping the program running properly.
- __TEXT segment migration: Moves some segments in the __TEXT segment of executable files to other segments, improving the compression efficiency of executable files. [Toutiao optimization practice: iOS package size binary optimization, a line of code to reduce the download size of 60 MB];
- .
The last
This article summarizes some commonly used slimming methods, of course, different project requirements and business scenarios will produce some corresponding slimming methods, you can find some better and better slimming techniques according to their own business characteristics.
Finally, have a great weekend!
Let’s be CoderStar!
A link to the
- Worst engineering disaster I ever experienced at Uber
- IOS installation package slimming practice
- Toutiao iOS package size optimization – new phase, new practice
- Dry goods | headlines today iOS installation package size optimization – train of thought and practice
- IOS package size binary optimization, a line of code to reduce the download size of 60 MB
- Explore WebP for a few things
- Palette Images
- IOS PNG Usage Guide
- Compress PNG Files for iOS
- IOS App weight loss
- The iOS Install Pack (Part 1)
- The iOS Install Pack is slimmer (part 2)
There is a technology circle and a group of fellow public is very important, to my technology public number, here only talk about technology dry goods.
Wechat official account: CoderStar