When developing a terminal, the first thing to consider is the rendering of views and animations, switching, etc. The most direct experience of users when using an app is whether the interface looks good, whether the animations are dazzling, and whether the sliding flow is smooth. The UI is the facade of the app, and its experience accompanies the entire process of the user using the app. If the UI fails, the user will not have the desire to open the app a second time. iOS provides developers with a rich framework (UIKit, Core Animation, Core Graphic, OpenGL, etc.) to meet various development needs from top to bottom. I have to say that Apple is awesome. You don't need to understand the principles behind many interfaces to get started and meet most of your needs. However, if you encounter performance problems, it's easy to be at a loss. Ease of use and optimization are contradictory. Just like ARC, it's very enjoyable to use when you don't encounter memory problems. Once you encounter them, you will be required to understand the memory mechanism of iOS better than when using MRC. The same is true for UI. Moreover, as an employee of Tencent, of course we can't just know how to use it. We must know the whys and the whys. Okay, without further ado, let's get to the point: see how iOS renders views and animations, and how to optimize when we encounter rendering performance problems. (Note: The following content is some of the author's experience and summary, welcome to discuss!) Let's first take a look at the official description of Core Animation: It can be seen that the core of iOS rendering view is Core Animation. From the bottom to the top, it is GPU->(OpenGL, Core Graphics)->Core Animation->UIKit. On iOS, animation and view rendering are actually done in another process (hereinafter we call this process render server). Before iOS 5, this process was called SpringBoard, and after iOS 6 it was called BackBoard. The following picture shows the progress of the entire system when using the project to record a video (a large number of view rendering): You can clearly see the status of the BackBoard process. The various stages of view or animation rendering on iOS: There are 4 stages inside the APP:
2 stages outside the APP: When this data reaches the render server, it will be deserialized into a render tree. Then the render server will do the following two things:
If you are doing an animation, the last two steps will be repeated until the animation is finished. We all know that the screen refresh rate of iOS devices is 60HZ. If the above steps cannot be completed within one refresh cycle (1/60s), it will cause frame drops. Let's see which operations may consume too much CPU or GPU and cause frame drops.
Notes on rendering performance optimization: Hidden drawing: Both CATextLayer and UILabel draw text into the backing image. If the frame of a view containing text is changed, the text will be redrawn. Rasterize: When using the layer's shouldRasterize (remember to set the appropriate layer's rasterizationScale), the layer will be forced to draw to an offscreen image and cached. This method can be used to cache layers that are time-consuming to draw (such as those with more gorgeous effects) but are not often changed. If the layer changes frequently, it is not suitable. Off-screen drawing: Use rounded corners, layer masks, and drop shadows effects by using stretchable images. For example, to achieve rounded corners, assign a circular image to the content property of the layer. And set the contentsCenter and contentScale properties. Blending and Overdraw: If a layer is completely covered by another layer, the GPU will optimize and not render the covered layer, but calculating whether a layer is completely covered by another layer is very CPU-intensive. Blending the colors of several semi-transparent layers together is also very CPU-intensive. What we are going to do:
This will reduce blending and overdraw. If you use an image, try to avoid setting the image's alpha to transparent. If some effects require the fusion of several images, let the designer draw it with one picture, and don't let the program merge them dynamically when running. OK, now that we have introduced some points to note about rendering optimization, let’s look at some specific examples using the Core Animation instrument and the GPU driver. Core Animation:
The following two pictures show the measurement of the semi-transparent layer of the project details page. You can see that there are still many semi-transparent layers on the details page, but it does not mean that there are many semi-transparent layers and a large range of them needs to be optimized. You need to refer to the measurement of the GPU driver to see, which will be introduced below. Color Hits Green and Misses Red: When using shouldRasterize, the layer drawing will be cached. If the rasterized layer needs to be redrawn, it will be marked in red. Below is the case where the cell of the Kugou message list is set to shouldRasterize = YES. The backing image of each cell's layer will be cached. If the tableview is scrolled down, the cell will be reused, so the layer will be redrawn and marked in red. Color Offscreen-Rendered Yellow: If you want to do offscreen drawing, it will be marked in yellow. Below is the homepage of the project. Since the circular avatar is implemented by setting the property of roundedCorner, it will trigger offscreen drawing. The Core Animation template only allows developers to intuitively see which areas may need optimization, but whether to optimize or not still depends on the performance of the GPU driver. GPU Driver Renderer Utilization - If this value is greater than 50%, it means that the GPU performance is limited by fill-rate, there may be too much Offscreen rendering, overdraw, and blending. Tiler Utilization - If this value is greater than 50%, it means there may be too many layers. Let’s take the project details page above as an example and look at the GPU driver measurements: You can see that the Renderer Utilization is about 20%, and the Tiler Utilization is 15%, so there is no need for optimization. (Of course, we are not considering the CPU usage here, but only based on some measurements of the core animation template above, we can say that there is no need for targeted optimization.) What I want to say here is that the above points only provide us with optimization directions and ideas when we encounter rendering performance problems. Optimization often means more complex and difficult to understand code. Don't over-optimize when you don't encounter rendering performance problems. I hope this helps you all! |
<<: The weirdest, most disruptive, and coolest science/tech stories of 2015
In this case, an advertiser in the education and ...
Stegosaurus is one of the most well-known dinosau...
After three years of fighting the epidemic, weari...
When you think of cactus, what comes to mind firs...
Having solved its capital chain crisis, NIO is ri...
This week's Internet industry was full of ups...
Behavior-driven development (BDD) bridges the gap...
B2C companies have many ways to use social media,...
□ Feng Weimin Recently, the international geologi...
What should I pay attention to when developing We...
[[127006]] Emotional communication between brands...
The Spring Festival, as the most important tradit...
In the ocean, there is an animal with the same bl...
Course Catalog other 03rd issue of Zhiliangke 47 ...
Biden talks infrastructure Background made in Chi...