I. Optimization of App startup

1.App startup can be divided into two types

  • Cold Launch: Start an APP from scratch
  • Warm Launch: The APP is already in memory and alive in the background. Click the icon again to Launch the APP
    • The optimization of APP startup time is mainly for cold startup
    • DYLD_PRINT_STATISTICS = 1 DYLD_PRINT_STATISTICS = 1 DYLD_PRINT_STATISTICS = 1 DYLD_PRINT_STATISTICS = 1
    • If you need more detailed information, set DYLD_PRINT_STATISTICS_DETAILS to 1

2.App cold start can be divided into four stages

  • Dyld loading executables, dynamic libraries (recursive loading)
  • runtime
  • After the main() function executes
  • After rendering the first screen
2.1 about dyld

  • On Mac and iOS, /usr/lib/dyld is used to load dynamic libraries

  • Dynamic Link Editor, dynamic link editor

  • Dynamic loader

  • The source code of dyld opensource.apple.com/tarballs/dy…

    • Dyld initializes the dynamic library first and then the executable file of the App.Copy the code

Using MachOView (github.com/gdbinit/Mac…). View the loading process as shown above

Note 1: If DYLD_PRINT_LIBRARIES is set or dynamic library loads are checked under Run /diagnostics, dyLD will print what libraries are loaded

Note 2: DYLD_PRINT_STATISTICS_DETAILS Specifies the start time of printing

Note 3: Dyly can also extract apple native library methods: 1: launch-cache/dsc_extractor. CPP file remove #if(0) and previous, #endif also delete 2: Clang++ -o dsc_extractor dsc_extractor. CPP to generate executable 3:./dsc_extractor dyld_shared_cache_armv7s armv7s to extract)

2.2 the runtime

Source: opensource.apple.com/source/objc… Source code analysis may refer to: www.jianshu.com/p/3019605a4…

When you start your APP, the Runtime does the following

  • Map_images is called for parsing and processing of executable file contents
  • Call call_load_methods in load_images, call all Class and Category +load methods to initialize various objC structures (register objC classes, initialize Class objects, and so on)
  • Calls C++ static initializers and functions modified by attribute(((constructor))
  • Up to this point, all symbols (Class, Protocol, Selector, IMP,…) in executables and dynamic libraries All have been successfully loaded into memory in the format managed by the Runtime
2.3 After the main function is executed

After the main () function performs stage, refers to from the main () function performs, into the appDelegate didFinishLaunchingWithOptions method first screen rendering completes relevant methods.

  • Initialize the read and write operations of the configuration file on the first screen
  • Read big data from the first screen list
  • A lot of calculations for the first screen rendering, etc
Conclusion:

The dyLD is responsible for the startup of the APP, loading the executable into memory, loading all dependent dynamic libraries, and loading them into objC defined structures by the Runtime. After all initialization, DyLD calls main, followed by UIApplicationMain. Application of AppDelegate: didFinishLaunchingWithOptions: method

3.App startup optimization

According to different stages

  • dyld
    • Reduce dynamic libraries, merge some dynamic libraries (periodically purge unnecessary dynamic libraries). Reduce dynamic library loading. Each library has its own dependencies, and Apple recommends using fewer dynamic libraries. Apple allows up to six non-system dynamic libraries to be merged into one.
    • Reduce the number of Objc classes and classes, reduce the number of selectors (periodically clean up unnecessary classes and classes)
    • Reduce the number of C++ virtual functions and reduce the number of C++ global variables
    • Swift uses structs as much as possible
  • runtime
    • Replace all attributes ((initialize), C++ static constructors, and ObjC’s + loads with the +initialize and dispatch_once methods, since a +load() method substitution at runtime costs 4 milliseconds.
  • After the main() function executes
    • Optimization at the function level: from the start of main() function to the completion of the first screen rendering, only the first screen related services are processed, the initialization of other non-first screen services, listening registration, configuration file reading is done after the completion of the first screen rendering
    • ReactiveCocoa does not create a signal for 6ms, +load() executes once for 4ms
    • App Time detection
    • Xcode’s own Time Profiler captures the main thread method call stack and calculates the Time of each method over a period of Time
    • To hook objc_msgSend method to master all the methods of execution opensource.apple.com/source/objc objc_msgSend source code…
    • Fackbook has opened source fishhook’s code github.com/facebook/fi… Its general idea is: through rebinding symbol, to achieve the HOOK of c method. Dyld binds the lazy and non-lazy symbols by updating Pointers in specific parts of the _DATA segment of the Mach-O binary. By checking where each symbol is updated in the rebind_symbol, you can find the replacement to rebind the symbols.
    • Delay as much as possible without affecting the user experience, and don’t put everything into the finishLaunching method u load on demand
    • Instead of using a XIB, load the home page view directly with code
    • NSUserDefaults actually produces a plist file in the Library folder. If the file is too large to read into memory at one time, it may take a long time to evaluate the impact. If it takes a long time, it needs to be split (consider old overwrite installation compatibility issues).
    • Each time printing in NSLog mode will implicitly create a Calendar, so it is necessary to delete the log entered by each business party at startup, or output the log only for the internal test version
    • Check whether all network requests sent during application startup can be unified in asynchronous threads

Two, the installation package thin

1. Installation package (IPA) is mainly composed of executable files and resources

  • Resources (pictures, audio, video, etc.)
  • Take lossless compression
  • Remove unused resources: github.com/tinymind/LS…

2. Thin executable files

2.1 Compiler optimization
  • Strip Linked Product, Make Strings read-only, Symbols Hidden by Default set to YES
  • Disable exception support, Enable C++ Exceptions, Enable Objective-C Exceptions set to NO, Other C Flags add -fno-exceptions
2.2 use AppCode

(www.jetbrains.com/objc/) Detect unused Code: menu bar -> Code -> Inspect Code

2.3 Write LLVM plug-in to detect duplicate code and uncalled code
2.4 Generating a LinkMap file, you can view the specific components of the executable file

2.5 Third-party tools can be used to parse LinkMap files:Github.com/huanxsd/Lin…

Three, the problem of caton

3.1 CPU and GPU

  • CPU (Central Processing Unit)

    Object creation and destruction, object property adjustment, layout calculation, text calculation and typesetting, image format conversion and decoding, image drawing (Core Graphics)

  • Graphics Processing Unit (GPU)

    Texture rendering

  • In iOS, it is double buffering mechanism, with frame caching before and frame caching after

3.2 Optimization Direction

  • Minimize CPU and GPU resource consumption
  • Try to use lightweight objects, such as CALayer instead of UIView, for places that don’t handle events
  • Don’t make frequent calls to UIView properties such as frame, bounds, Transform, etc., and minimize unnecessary changes
  • Try to calculate the layout in advance, adjust the corresponding attributes at one time if necessary, do not modify the attributes more than once
  • Autolayout consumes more CPU resources than setting the frame directly
  • The image size should be exactly the same as the UIImageView size
  • Control the maximum number of concurrent threads
  • Try to avoid the display of a large number of pictures in a short period of time, as far as possible to display a composite of multiple pictures
  • The maximum texture size that GPU can process is 4096×4096. Once the texture size exceeds this size, IT will occupy CPU resources for processing, so the texture size should not exceed this size
  • Minimize the number of views and levels
  • Reduce transparent views (alpha<1) and set Opaque to YES for opaque views
  • Try to put time-consuming operations into child threads
    • Text processing (dimensional calculation, rendering) p
    • Image processing (decoding, rendering)

3.3. Off-screen rendering

  • Try to avoid off-screen rendering
  • In OpenGL, the GPU has 2 rendering methods
    • On-screen Rendering: Renders On the Screen buffer currently used for display
    • Off-screen Rendering: Creates a new buffer outside the current Screen buffer for Rendering
  • Off-screen rendering is a performance drain
    • A new buffer needs to be created
    • In the whole process of off-screen rendering, the context needs to be changed several times, first from the current Screen (on-screen) to off-screen (off-screen); When the off-screen rendering is finished, the rendering results of the off-screen buffer are displayed on the screen, and the context needs to be switched from off-screen to the current screen
  • What actions trigger an off-screen rendering?
    • ShouldRasterize = YES p mask, layer
    • Layer. masksToBounds = YES and layer.cornerRadius > 0.
    • Shadow, layer.shadowXXX (shadowPath will not render off-screen if layer.shadowPath is set)

Memory leaks

One, find the leak point (two tools)

  • 1 > Analyze

    - Name: Static analysis tool - Search: Can be started by using the Product ->Analyze menu item - shortcut key: CMD+shift+b. -analyze mainly analyzes the following four problems: 1) logical errors: access to null Pointers or uninitialized variables; 2) Memory management errors, such as memory leakage; 3) Declaration error: never used variable; 4) Api call error: library and framework not included.Copy the code
  • 2 >Instruments

    - Learn name: dynamic analysis tool - Search: Product ->Profile menu item start - shortcut key: CMD + I. Brief introduction: It has a number of trace modules to dynamically analyze and track memory, CPU, and file systems.Copy the code

Fourth, power consumption optimization

  • Minimize CPU and GPU power consumption

  • Use less timer

  • Optimize I/O operations

    • Do not write small data frequently. It is better to write data in batches at a time
    • Consider dispatch_io for reading and writing large amounts of important data, which provides an API for asynchronously operating file I/O based on GCD. The system optimizes disk access with dispatch_io
    • For large amounts of data, it is recommended to use databases (such as SQLite and CoreData).
  • Network optimization

    • Reduce and compress network data
    • If the result of multiple requests is the same, try to use caching
    • Use breakpoint continuation, otherwise the same content may be transmitted multiple times when the network is unstable
    • Do not attempt to perform network requests when the network is unavailable
    • Allows users to cancel long-running or slow network operations and set appropriate timeouts
    • For example, when downloading video streams, instead of sending small packets, download the entire file directly or in large chunks. If you download ads, download several at a time and display them slowly. If you download emails, download several at a time, not one by one
  • Location optimization

    • If you just need to quickly determine the user’s location, it’s best to use the requestLocation method of CLLocationManager. After the locating is complete, the locating hardware is automatically powered off
    • If it’s not a navigation app, try not to update your location in real time and turn off location services when you’re done
    • Try to reduce the positioning accuracy, such as try not to use the highest accuracy kCLLocationAccuracyBest
    • Need background position, try to set up pausesLocationUpdatesAutomatically to YES, if the user is unlikely to move the system will automatically suspended position update
    • Try not to use startMonitoringSignificantLocationChanges, priority startMonitoringForRegion:
  • When the user moves, shakes or tilts the device, motion events are generated, which are detected by hardware such as accelerometers, gyroscopes and magnetometers. These hardware should be turned off when testing is not required

5. Reference materials

IOS boot optimization blog: www.zoomfeng.com/blog/launch…

Dyld source: opensource.apple.com/tarballs/dy…

Dyld introduction and analysis: www.jianshu.com/p/be413358c…

The runtime source: opensource.apple.com/source/objc…

The runtime source analysis: www.jianshu.com/p/3019605a4…

Objc_msgSend source: opensource.apple.com/source/objc…

Open source project Fishhook: github.com/facebook/fi…

Open Source project LSUR: github.com/tinymind/LS…

AppCode website: www.jetbrains.com/objc/

Open source project LinkMap: github.com/huanxsd/Lin…

GNUstep source www.gnustep.org/resources/d…

MachOView source: github.com/gdbinit/Mac…

Today’s headline iOS client startup speed optimization: techblog.toutiao.com/2017/01/17/…

IOS performance optimization github.com/skyming/iOS…