To see what happened, take a look at the last breakdown: iOS Performance Optimization (Beginner)

A profound

Through the performance of the primary optimization of the secret for a period of practice, Shaoxia should have a certain understanding of performance optimization, in the daily development of the code has some awareness of performance optimization, when the product teacher sister proposed a new interaction, must also be difficult to fall shaoxia.

In terms of lists, icon, headline, sub-title and content are often the elements of general APPS. Different typesetting results in different detailed effects. These are no longer problems for Shaoxia, the APP is silky smooth in silence. Looking at the product little sister that look in the eyes of admiration, cattle surging, blossoming, vows of eternal love will soon blurt out.

forays

But, the rivers and lakes change, you have been prepared.

I just didn’t think that day would come so soon.

That day product small pool put forward a new demand, in addition to the previous icon, big titles, headings, now want to add tags, labels have multiple used in a variety of activities, the location of the label to be decided according to the location of the title content, tags to be made rounded corners and borders, and list the height of each row to finally confirmed according to the content, the content is high, The content is short, and the icon should be round with a border and a little shadow, blah, blah, blah, blah, blah, blah. The product little sister said a lot in one breath, said you see stars, breath disorder, almost go crazy, spit blood, but looked at the little sister that as always happy and look forward to the eyes, had to secretly, steady, promised little sister’s needs. The girl is far away, looking at the shadow of the teacher sister far away, you crazy coding, but there is always a point can not break through, fluency can not meet the requirements, can not help but fall into meditation.

service

Primary performance optimization cheats can only deal with primary performance optimization problems. But the current requirements, many effects, many subviews, typesetting updates frequently, height of each line is different. The primary cheats don’t work very well anymore.

Shaxia don’t panic, old husband see you have been skilled in the primary performance optimization secrets, the foundation has been solid, now the performance optimization intermediate secrets to teach you.

To do a good job, you must first sharpen your weapons. If you want to defeat your opponents, you must have weapons in hand.

View FPS data directly in the APP:

CADisplayLink is a timer that is called at the same frequency as the screen refreshes.

The top talisman belongs to the Instrument:

If you want to use this magic weapon proficiently, you need to pay attention to two things

  1. Use release mode, close to the most real use environment, can obtain the most accurate data.
  2. With the real machine test, the simulator is still simulating, no matter how powerful it is. Only by offering different models of the real machine can it be optimized.

Xcode -> Product -> Profile -> Core Animation -> TimeProfile -> TimeProfile -> Xcode -> Product -> Profile -> Core Animation -> TimeProfile -> TimeProfile

with

To optimize the performance, perform the following steps: Modify the Instrument view Instrument View Instrument View….. Repeat until desired performance is achieved

CPU time-consuming operations can be viewed in the Instrument and modified and optimized, but how to optimize GPU operations?

After XCode9, you can see the optimized options under Xcode -> Debug > View Debugging > Rendering.

  • Color Blended Layers — areas where Layers are Blended will be marked red and areas where Layers are not Blended will be marked green. The direction is as little red as possible and as much green as possible.

  • Color Hits Green and Misses Red – When using shouldRasterize, if the layer is Green, it means that the cache is reused, and if the layer is Red, it means that the cache is not reused and is repeatedly created, which can cause performance problems.

  • Color Copied Images – If the GPU does not support the current image format, the image is given to the CPU for pre-processing and appears blue.

  • Color Misaligned Images – Detects if an image is stretched. This happens when the image Color is not aligned with the ImageView’s size, and is displayed as yellow. This can consume CPU resources.

  • Rendered Yellow Color Offscreen- Rendered Yellow — There are two types of ON-screen Rendering, where the GPU Rendering is rendered in the buffer of the current screen. Off-screen Rendering refers to the newly created buffer on the GPU where Rendering takes place outside the current screen. Creating a new buffer, switching the buffer and so on have a great impact on performance.

There are several behaviors that trigger off-screen rendering:

  1. A cornerRadius and masksToBounds trigger off-screen rendering when used together, but not when used alone.
  2. Set shadow and shodowPath = nil.
  3. The mask setting mask is triggered.
  4. ShouldRasterize inappropriate use of layer.shouldRasterize triggers off-screen rendering.
  5. AllowsGroupOpacity is enabled by default after iOS7; When the layer opacity! Is triggered when there is a subLayer or background image.
  6. Layer. AllowsEdgeAntialiasing after iOS8 system may have been optimized, will not trigger the off-screen rendering, will not affect performance.
  7. Rewrite drawRect.

Shaoxia read the above moves, they can quickly find out the opponent’s flaws.

invulnerable

To find out the enemy’s flaws, Shaoxia should develop detailed coping strategies, and watch the timing, in order to make the enemy.

My old man will show you how to make enemies:

  • Color Blended the Layers:

    • UIView backgroundColor should not be set to clearColor, preferably the same color as superView backgroundColor.
    • Images avoid images with alpha channels, whether local or background returned images. What? The design girl said no, Sonny it’s all about your charm.
  • Color Hits Green and Misses Red: In primary performance optimization, the appropriate use of shouldRasterize is detailed.

  • Color Copied Images: Development process to note the image format

  • Color Misaligned Images: Try to set the image size to be the same as the UIImageView.

  • Color offscreen-Rendered Yellow: This is a major point of optimization, rendered on a case-by-case basis for off-screen rendering

The key comes, the optimization of off-screen rendering moves, shaoxia look carefully

  • Set the cornerRadius:

UIView: If view.layer.contents is empty, you can set the corner by setting view.layer.cornerRadius and view.backgroundColor or view.layer.border. You do not need to set masksToBounds to YES and no off-screen rendering will occur.

Layer. borderColor = uicolor.red. CgColor View.layer. borderWidth = 1.0 // Set with the background layer. The cornerRadius = 3.0 the backgroundColor = UIColor. Green / / or the view of the same effect. The layer. The backgroundColor = UIColor.green.cgColorCopy the code

UILabel: Settings are similar to UIView, except that label.backgroundColor and layer.cornerRadius will not work. Need to set up the label. The layer. The backgroundColor and layer will take effect cornerRadius.

BorderColor = Uicolor.red.cgcolor View.layer.borderWidth = 1.0Copy the code

UITextField: with rounded corner effect, set different styles to achieve the effect.

UITextView: Same as UIView.

Layer. cornerRadius and layer.masksToBounds = YES However, this operation is bound to produce off-screen rendering. In order to avoid off-screen rendering, commonly used optimization methods are as follows:

  • Redraw the image, make an image with rounded corners, and then set it to UIImageView.

    func redrawImage(originImage: UIImage, rectSize: CGSize, cornerRadius: CGFloat) -> UIImage? {
       UIGraphicsBeginImageContextWithOptions(rectSize, false, UIScreen.main.scale)
       if let context = UIGraphicsGetCurrentContext() {
             let rect = CGRect(origin: CGPoint.zero, size: rectSize)
             let path = UIBezierPath(roundedRect: rect, byRoundingCorners: .allCorners, cornerRadii: CGSize(width: cornerRadius, height: cornerRadius))
             context.addPath(path.cgPath)
             context.clip()
             originImage.draw(in: rect)
             context.drawPath(using: .fillStroke)
             let roundedImage = UIGraphicsGetImageFromCurrentImageContext()
             UIGraphicsEndImageContext()
             return roundedImage
            }
        returnNil} dispatchqueue.global (qos:.default). Async {dispatchqueue.main. Async {// Dispatchqueue.main.Copy the code
  • Cover a partially transparent, partially occluded image over the original UIImageView with curves to round the corners of the image.

    Func getRundedCornerImage(radius: CGFloat, rectSize: CGSize, fillColor: UIColor) -> UIImage? Func getRundedCornerImage(radius: CGFloat, rectSize: CGSize, fillColor: UIColor) { UIGraphicsBeginImageContextWithOptions(rectSize,false, UIScreen.main.scale)
      if let currentContext = UIGraphicsGetCurrentContext() {
        let rect = CGRect(origin: .zero, size: rectSize)
        let outerPath = UIBezierPath(rect: rect)
        let innerPath = UIBezierPath(roundedRect: rect,
                                   byRoundingCorners: .allCorners,
                                   cornerRadii: CGSize(width: radius, height: radius))
        currentContext.setBlendMode(.normal)
        fillColor.setFill()
        outerPath.fill()
      
        currentContext.setBlendMode(.normal)
        innerPath.fill()
        let roundedCornerImage = UIGraphicsGetImageFromCurrentImageContext()
      UIGraphicsEndImageContext()
        return roundedCornerImage
        }
      returnNil} // Add the generated image above the image that needs rounded cornersCopy the code
  • Set shadow shadow:

    Setting shadowPath can solve the off-screen rendering problem.

    Self. ShadowView. Layer. The shadowColor = UIColor. Gray. The cgColor self. ShadowView. Layer. ShadowOpacity = 0.2 Self. ShadowView. Layer. ShadowRadius = 3.0 self. ShadowView. Layer. ShadowOffset = CGSize (width: 1, height: 1) self.shadowView.layer.shadowPath = UIBezierPath(rect: view.bounds).cgPathCopy the code

    Of course, as with the rounded corner solution, you can use a shaded graph to curve the problem.

    func getRundedCornerShadowImage(originImage: UIImage, rectSize: CGSize, roundedRadius: CGFloat, shadowColor: UIColor, shadowOffset: CGSize, insetX: CGFloat, insetY: CGFloat) -> UIImage? {
     UIGraphicsBeginImageContextWithOptions(rectSize, false, UIScreen.main.scale)
     if let currentContext = UIGraphicsGetCurrentContext() {
         let rect = CGRect(origin: .zero, size: rectSize)
         let shadowPath = UIBezierPath(roundedRect: rect.insetBy(dx: insetX, dy: insetY),
                                 byRoundingCorners: .allCorners,
                                 cornerRadii: CGSize(width: roundedRadius, height: roundedRadius))
         currentContext.setShadow(offset: shadowOffset, blur: roundedRadius, color: shadowColor.cgColor)
         currentContext.addPath(shadowPath.cgPath)
         shadowPath.fill()
    
         let imagePath = UIBezierPath(roundedRect: rect.insetBy(dx: insetX, dy: insetY),
                                       byRoundingCorners: .allCorners,
                                       cornerRadii: CGSize(width: roundedRadius, height: roundedRadius))
         currentContext.addPath(imagePath.cgPath)
         currentContext.clip()
         originImage.draw(in: rect.insetBy(dx: insetX, dy: insetY))
         currentContext.strokePath()
         
         let image = UIGraphicsGetImageFromCurrentImageContext()
         UIGraphicsEndImageContext()
         return image
     }
     return nil
    }  
    Copy the code
  • Set mask mask:

    Setting the mask must trigger an off-screen rendering. The process of mask is roughly opposite to the process of view mixing. For example, in an image, there is a circular space in the middle that is transparent and the edge is white. If the view is directly superimposed on a head, the effect of round head will be presented, but if the mask is used, the effect of transparent white edge in the middle will be displayed. Therefore, performance-sensitive interfaces can be operated in a way that has less impact on performance, rather than using masks.

  • Layer. AllowsGroupOpacity, layer. AllowsEdgeAntialiasing:

    These two operations do not have a significant impact on performance.

  • DrawRect:

    DrawRect can consume a lot of memory and cause off-screen rendering and should be avoided as much as possible.

perfection

The above moves, shaoxia can be optimistic, in the future when good practice, won the girl’s heart is within reach.

Go and find your sister.

To see what happens next, watch the next breakdown: iOS Performance Optimization (Intermediate +) : Asynchronous drawing