• Whichever CPU or GPU blocks the display process will cause frames to drop

CPU consumption causes and solutions

  • Object creation
    • Allocating memory, adjusting properties, file manipulation
    • Use lightweight objects whenever possible
    • Controls that do not need to respond to events use CALayer instead of UIView
    • Use pure code instead of NIB
    • Delay object creation events to avoid repeated creation (such as lazy loading)
  • Object to adjust
    • Avoid UIView property adjustments
    • Avoid view level and Layer level adjustments (including adding and removing views)
  • Layout calculation
    • The layout is calculated in advance in the background process, cached, and set up once
  • AutoLayout
    • Can cause serious performance problems for complex views, and AutoLayout’s CPU consumption increases exponentially as the number of views increases
  • The text calculated
    • If an interface contains a large amount of text (such as weibo and wechat moments, etc.), text width and height calculation will occupy a large portion of resources and is inevitable. If you have no special requirements for text display, you can refer to the internal implementation of UILabel[NSAttributedString boundingRectWithSize:options:context:]To calculate the width and height of the text, use –[NSAttributedString drawWithRect:options:context:]To draw the text. Although these two methods perform well, they still need to be put into background threads to avoid blocking the main thread.

If you draw text in CoreText, you can create a CoreText typeset object and do the calculation yourself, and the CoreText object can be saved for later drawing.

  • Text rendering
    • All text content controls that can be seen on the screen, including UIWebView, are at the bottom of the page formatted and drawn as bitmaps through CoreText. Common text controls (UILabel, UITextView, etc.), its typesetting and drawing are carried out in the main thread, when the display of a large number of text, the CPU pressure will be very large. There is only one solution, and that is a custom text control that asynchronously draws text using TextKit or the low-level CoreText. Once the CoreText object is created, it can directly obtain the width and height of the text, avoiding multiple calculations (once when the UILabel size is adjusted, and again when the UILabel is drawn). CoreText objects take up less memory and can be cached for later multiple renders.
  • Image rendering
    • When you create an image using UIImage or CGImageSource methods, the image data is not immediately decoded. The image is set to UIImageView or calayer.contents, and the data in the CGImage is decoded before the CALayer is submitted to the GPU. This step occurs on the main thread and is unavoidable. If you want to get around this mechanism, it is common to draw images into CGBitmapContext in the background line and then create images directly from the Bitmap. At present, the common network photo library has this function.
  • Image drawing
    • Drawing an image usually refers to the process of drawing an image onto a canvas using methods that begin with CG, and then creating and displaying the image from the canvas. The most common place to do this is inside [UIView drawRect:]. Since CoreGraphic methods are usually thread-safe, drawing images can easily be put into background threads. The process for a simple asynchronous drawing looks something like this (it’s much more complicated than this, but the principle is the same) :