The cause of caton
After the arrival of VSync signal, the graphics service of the system will notify the App through CADisplayLink and other mechanisms, and the main thread of the App will start to calculate the display content in the CPU, such as view creation, layout calculation, picture decoding, text drawing, etc. Then THE CPU will submit the calculated content to the GPU, which will transform, synthesize and render. The GPU then submits the rendering result to the frame buffer and waits for the next VSync signal to be displayed on the screen. Due to the VSync mechanism, if the CPU or GPU does not complete the content submission within a VSync period, the frame will be discarded and displayed at the next opportunity, while the display will keep the previous content unchanged. That’s why the interface gets stuck.
During development, excessive pressure on either CPU or GPU will lead to frame drop. Therefore, it is necessary to evaluate and optimize the pressure on CPU and GPU respectively during development.
CPU and GPU in iOS devices
CPU
Loading resources, object creation, object adjustment, object destruction, layout calculation, Autolayout, text calculation, text rendering, image decoding, and Core Graphics are all done on the CPU.
GPU
The GPU is a processing unit specifically designed for highly concurrent graphics computation. It uses less power than the CPU to complete the work and the floating point computing power of the GPU exceeds that of the CPU by a large margin.
GPU rendering performance than the CPU efficiency a lot, at the same time, the load and the consumption of the system is also lower, so in development, we should try to get the CPU is responsible for the main thread of the UI, the graphical display work related to the GPU to deal with, when it comes to the rasterizer when some of the work, the CPU will also be involved, which are described in more detail later.
Compared to the CPU, the GPU can do a single thing: take the submitted Texture and vertex description, apply the transform, mix and render, and then print it to the screen. The main things you can see are textures (pictures) and shapes (vector shapes for triangle simulation).
CPU and GPU collaboration
As can be seen from the figure above, to display a view on the screen, CPU and GPU need to work together. CPU calculates the displayed content and submits it to GPU, and GPU puts the result into frame cache after rendering. Then the video controller will read the data of frame buffer line by line according to VSync signal and transfer it to the display through possible digital-to-analog conversion.
The buffer mechanism
IOS uses double buffering. That is, THE GPU will pre-render a frame and put it into a buffer (front frame cache) for the video controller to read. After the next frame is rendered, the GPU will directly point the pointer of the video controller to the second buffer (post frame cache). When your video controller has finished reading one frame and is ready to read the next, the GPU will wait for the VSync signal from the display. The front frame cache and the back frame cache will switch instantly, and the back frame cache will become the new front frame cache, while the old front frame cache will become the new back frame cache.
Optimization scheme
The causes and solutions of CPU resource consumption and GPU resource consumption are introduced in detail in YY’s iOS interface smoothness skills, including most of the scenarios in development, which can help us quickly locate the causes of the lag and quickly solve the lag.
Here are some common optimizations!
TableViewCell reuse
The cellForRowAtIndexPath: callback creates only the instance, returns the cell quickly, and does not bind the data. Bind data (assign) at willDisplayCell: forRowAtIndexPath:.
Highly cache
When the tableView slides, heightForRowAtIndexPath: will be called repeatedly. When the cell height needs to be adaptive, each callback will calculate the height, which will cause the UI to get stuck. To avoid repeating meaningless calculations, cache height is required.
How to cache?
- Dictionary, NSCache.
- UITableView-FDTemplateLayoutCell
View hierarchy optimization
Do not create views dynamically
- Under the premise of controllable memory, cache
subview
. - Make the best use
hidden
.
Reducing view hierarchy
- To reduce
subviews
The number,layer
Draw elements. - To use less
clearColor
.maskToBounds
, shadow effects, etc.
Reduce unnecessary drawing operations
The picture
- Don’t use
JPEG
Should be usedPNG
The image. - Child thread predecode (
Decode
), the main thread renders directly. Because whenimage
There is noDecode
, and directly assign toimageView
Will conduct aDecode
Operation. - Optimize image size and try not to zoom dynamically (
contentMode
). - Combine as many pictures as possible into one for display.
Reduce transparent View
Using transparent views gives rise to blending, which in iOS graphics processing refers primarily to the calculation of blending pixel colors. The most intuitive example is when we overlay two layers together. If the first layer is transparent, the final pixel color calculation needs to take into account the second layer. This process is called Blending.
Causes of blending:
UIView
thealpha
<1
.UIImageView
theimage
containsalpha channel
(even ifUIImageView
thealpha
is1
, but as long as theimage
If it contains transparent channels, it will still causeblending
).
Why does blending cause performance loss?
The reason is straightforward: if a layer is opaque, the system simply displays the color of the layer. If the layer is transparent, it will cause more calculation because the other layer needs to be included in the calculation of the blended color.
opaque
Set toYES
, reduce performance consumption becauseGPU
Will not do any composition, but simply copy from this layer.
Reduce off-screen rendering
Off-screen rendering refers to rendering an image once before drawing it to the current screen.
In OpenGL, the GPU screen can be rendered in the following two ways:
-
On-screen Rendering refers to the on-screen Rendering operation performed by the GPU in the on-screen buffer currently used for display.
-
Off-screen Rendering refers to when the GPU creates a new buffer outside the current Screen buffer to render.
Why does off-screen rendering stall? It mainly includes two aspects:
- Create a new buffer.
- Context switch, the entire process of off-screen rendering requires multiple context switches (
CPU
Rendering andGPU
First, it switches from on-screen to 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. Context switching is costly.
Off-screen rendering is triggered when the following properties are set:
-
ShouldRasterize, rasterize
-
The layer mask, mask
-
AllowsGroupOpacity is YES, and the value of layer.opacity is less than 1.0
-
Layer. cornerRadius and set layer.masksToBounds to YES. This can be done using clipped images or layer drawings.
-
Layer. shadows, (denoting related attributes beginning with shadow), uses shadowPath instead.
There are two different ways to draw shadows: no shadowPath
Using shadowPath
Performance difference, as shown below:
Optimization suggestions for off-screen rendering
- use
ShadowPath
The specifiedlayer
Shadow effect path. - Use asynchronously
layer
Rendering (Facebook
Open source asynchronous drawing frameworkAsyncDisplayKit
). - Set up the
layer
theopaque
A value ofYES
To reduce complex layer composition. - Try to use transparency without inclusion (
alpha
Channel image resources. - Try to set up
layer
The size value of the - The most efficient solution is to have the artist cut the image into rounded corners.
- In many cases, the user uploads images for display and can handle rounded corners on the client side.
- Use code to manually generate rounded corners
image
Set to displayView
On, the use ofUIBezierPath
(Core Graphics
Frame) draw the rounded picture.
ShouldRasterize should be used properly
Rasterization is to transfer GPU operations to CPU, generate bitmap cache, and directly read reuse.
Advantages:
CALayer
Will be rasterizedbitmap
.shadows
,cornerRadius
Such effects will be cached.
Disadvantages:
- Update the already rasterized
layer
, will cause off-screen rendering. bitmap
More than100ms
It will be removed if it is not used.- The Size of the cache is 2.5X Screen Size due to system restrictions.
shouldRasterize
Suitable for static page display, dynamic page can add overhead. If you set it upshouldRasterize
forYES
Remember the Settings, toorasterizationScale
forcontentsScale
.
Asynchronous rendering
Draw in child thread, render in main thread. For example VVeboTableViewDemo
Rational use -drawRect:
You might be surprised to see a number of developers blogging about performance tuning using -drawRect: to optimize performance. But I don’t really recommend using the -drawrect: method without thinking. Here’s why:
When you load a view with UIImageView, the view still has a CALayer, but it doesn’t apply for a backup store. Instead, it uses a buffer that uses an off-screen render, uses CGImageRef as the content, and uses the render service to draw the image data to the frame. When we scroll through the view, the view will reload, wasting performance. So with the -drawRect: method, CALayer is preferred for drawing layers. Because using CALayer’s -drawinContext:, Core Animation will apply a back-up store for this layer to hold the bitmaps drawn by those methods. The code inside those methods will run on the CPU, and the results will be uploaded to the GPU. The performance is better this way.
-drawRect: is recommended for static pages, but not for dynamic pages.
According to the need to load
- Partial refresh, refresh one
cell
Will be able to solve, determined not to refresh the wholesection
Or the entiretableView
.Refresh the minimum cell element.
- Use Runloop to improve the smoothness of the slide. Load the content when the slide stops, such as a flash (quick slide). There is no need to load the content and you can fill it with the default placeholders.
About Performance Testing
The first thing we need to do after we have graphics performance problems, slides, and animations that aren’t smooth enough is to locate the problem. And this process is not only to rely on experience and exhaustive method of exploration, we should use the context, sequence of scientific means to explore.
First, we need to have a model for locating problems. We can follow this order step by step to locate the problem.
- Positioning frame rate, in order to give the user a smooth feeling, we need to keep the frame rate at
60
Around the frame. When encountering problems, we first check to see if the frame rate is maintained60
The frame. - Locate the bottleneck, what is it
CPU
orGPU
. We want to have as little occupancy as possible, one for fluency, and two for saving power. - Check to see if anything unnecessary has been done
CPU
Rendering, for example, we rewrote some of itdrawRect:
Which we don’t need and shouldn’t. We hope toGPU
Take on more work. - Check to see if there are too many off-screen renderings, which will cost
GPU
Resources, as already analyzed. Off-screen rendering can causeGPU
Need to be constantlyonScreen
andoffscreen
Perform a context switch. We want to have less off-screen rendering. - Check to see if we have too much
Blending
.GPU
Rendering an opaque layer saves resources. - Check whether the image format is in common use and whether the size is normal. If a picture format is not
GPU
If yes, you can only passCPU
To render. Usually we haveiOS
Should be used in developmentPNG
Format, some of the material I read before also pointed out that Apple specifically forPNG
The format is optimized for rendering and compression algorithms. - Check if there are any resources consuming
View
Or effect, we need reasonable and moderate use. - Finally, we need to check before we
View
Is there something wrong with the hierarchy? For example, sometimes we keep adding and removingView
, sometimes inadvertentlybug
From happening.
Test tools:
Core Animation
.Instruments
Test tool for graphics performance problems in.view debugging
Xcode comes with view hierarchy.reveal
, view hierarchy.
Refer to the article
- Draws pixels to the screen
- IOS graphics principles and off-screen rendering, in 1.4.1,
That's why CALayer has a property called Opaque. If this property is NO, the GPU will not do any composition, but will simply copy from this layer, not needing to consider anything underneath it (since everything is obscured by it).
In theopaque
Properties forNO
.GPU
Will not do any composition, this sentence is incorrect, should be forYES
.GPU
I’m not going to do any composition. - IOS tips for keeping the interface smooth
- Advanced Graphics and Animations for iOS Apps(session 419)
- Performance tuning with ASDK – Improve iOS interface rendering performance
- Designing for iOS: Graphics & Performance
- Optimization analysis of iOS off-screen rendering
- Summary of iOS view rendering and performance optimization
- IOS off-screen rendering
- Deep understanding of mobile optimization for off-screen rendering
- IOS fluency performance optimization, CPU, GPU, off-screen rendering
- IOS graphics performance optimization collection
- Off-screen rendering optimization: Example demonstration + performance test
If there is any content error, welcome to issue correction.
I would like to recommend an excellent iOS communication platform. The partners in the platform are all excellent iOS developers. We focus on sharing technology and exchanging skills. Welcome to join (if you want to enter, you can add xiaobian wechat)
Author: LaiYoung_
Link: https://juejin.cn/post/6844903590138478600
Source: Nuggets