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, cachesubview.
  • Make the best usehidden.
Reducing view hierarchy
  • To reducesubviewsThe number,layerDraw elements.
  • To use lessclearColor.maskToBounds, shadow effects, etc.
Reduce unnecessary drawing operations

The picture

  • Don’t useJPEGShould be usedPNGThe image.
  • Child thread predecode (Decode), the main thread renders directly. Because whenimageThere is noDecode, and directly assign toimageViewWill conduct aDecodeOperation.
  • 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:

  • UIViewthealpha < 1.
  • UIImageViewtheimagecontainsalpha channel(even ifUIImageViewthealphais1, but as long as theimageIf 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.

  • opaqueSet toYES, reduce performance consumption becauseGPUWill 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 (CPURendering andGPUFirst, 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

  • useShadowPathThe specifiedlayerShadow effect path.
  • Use asynchronouslylayerRendering (FacebookOpen source asynchronous drawing frameworkAsyncDisplayKit).
  • Set up thelayertheopaqueA value ofYESTo reduce complex layer composition.
  • Try to use transparency without inclusion (alphaChannel image resources.
  • Try to set uplayerThe 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 cornersimageSet to displayViewOn, the use ofUIBezierPath(Core GraphicsFrame) 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:
  • CALayerWill be rasterizedbitmap.shadows,cornerRadiusSuch effects will be cached.
Disadvantages:
  • Update the already rasterizedlayer, will cause off-screen rendering.
  • bitmapMore than100msIt will be removed if it is not used.
  • The Size of the cache is 2.5X Screen Size due to system restrictions.

shouldRasterizeSuitable for static page display, dynamic page can add overhead. If you set it upshouldRasterizeforYESRemember the Settings, toorasterizationScaleforcontentsScale.

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 onecellWill be able to solve, determined not to refresh the wholesectionOr 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.

  1. Positioning frame rate, in order to give the user a smooth feeling, we need to keep the frame rate at60Around the frame. When encountering problems, we first check to see if the frame rate is maintained60The frame.
  2. Locate the bottleneck, what is itCPUorGPU. We want to have as little occupancy as possible, one for fluency, and two for saving power.
  3. Check to see if anything unnecessary has been doneCPURendering, for example, we rewrote some of itdrawRect:Which we don’t need and shouldn’t. We hope toGPUTake on more work.
  4. Check to see if there are too many off-screen renderings, which will costGPUResources, as already analyzed. Off-screen rendering can causeGPUNeed to be constantlyonScreenandoffscreenPerform a context switch. We want to have less off-screen rendering.
  5. Check to see if we have too muchBlending.GPURendering an opaque layer saves resources.
  6. Check whether the image format is in common use and whether the size is normal. If a picture format is notGPUIf yes, you can only passCPUTo render. Usually we haveiOSShould be used in developmentPNGFormat, some of the material I read before also pointed out that Apple specifically forPNGThe format is optimized for rendering and compression algorithms.
  7. Check if there are any resources consumingViewOr effect, we need reasonable and moderate use.
  8. Finally, we need to check before weViewIs there something wrong with the hierarchy? For example, sometimes we keep adding and removingView, sometimes inadvertentlybugFrom happening.
Test tools:
  • Core Animation.InstrumentsTest tool for graphics performance problems in.
  • view debuggingXcode 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 theopaqueProperties forNO.GPUWill not do any composition, this sentence is incorrect, should be forYES.GPUI’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