Uikit Performance Tuning Practical explanation

Source: Internet
Author: User


Use sweep to view full-text dry

Bestswifter

In the process of using Uikit, performance optimization is an eternal topic. Many people have seen articles that analyze the optimization of sliding performance, but many of these articles only describe the optimization method but not the underlying principles, or obscure and the lack of practical experience of the reader's opportunity. Consider the following question whether you have a clear understanding of:

    1. Why should the control be set to be opaque, and if it is transparent, how does it affect how to detect this effect?

    2. Why do you want to use the correct size and format for the pictures in the cell, and how do I detect this effect if the error has any effect?

    3. Why is setting shadows and fillets likely to affect smoothness when sliding?

    4. What is the relationship between shouldrasterize and off-screen rendering and when should it be used?

This article will combine instrument analysis of factors affecting performance, propose optimization scheme and explain the principle behind, Project initial demo on my GitHub, strongly recommend each reader to download down as I step by step debugging, optimization. If you feel that you are helping yourself, you can show support for a star. Behind the picture more, traffic party cautious into.

Basic concepts

After opening the project, as long as the Customtablecell.swift file is available, it implements the custom UITableViewCell and the internal UI layout, because the focus is on performance optimization, and the code implementation is more casual.

First press COMMAND + I to open instrument, this article mainly uses the Core animation tool:

Open Core Animation debugging

Note that this debugging must use the real machine, and clicking on the red circle in the upper left corner will start recording. Novice may be unfamiliar, here is a brief introduction to the Debugging interface:

Debug interface

We need to know two of the two areas:

    1. Real-time FPS values are recorded here, and some of them are 0 because the screen is not sliding

    2. This is a priority, and then I'll take you through each of these debugging options

Someone with a game experience may be familiar with the concept of FPS. We know that any screen always has a refresh rate, such as the recommended refresh rate for the iphone is 60Hz, which means that the GPU refreshes the screen 60 times per second, so the interval between two refreshes is 16.67ms. During this time the screen content remains the same, called a frame, and FPS represents frames per second, which is how many frames per second are displayed. For static content, we don't need to consider its refresh rate, but when animating or sliding, the FPS value directly reflects how smooth the slide is.

Commissioning, optimization

Layer Blending

First we need to understand the concept of the pixel, every point on the screen is a pixel, like R, G, b three color composition (sometimes with alpha value). If multiple layers are covered in an area, the final display effect is affected by these layers. For example, the upper layer is blue (rgb=0,0,1), with a transparency of 50%, and the lower layer is red (rgb=1,0,0). Then the final display effect is purple (rgb=0.5,0,0.5). This color mix (blending) consumes a certain amount of GPU resources because it may actually be more than just two layers. If you want to display only the topmost blue, you can set its transparency to 100% so that the GPU ignores all layers below, thus saving a lot of unnecessary operations.

The first debug option "Color blended Layers" is used to detect where a layer blend has occurred and is marked with red. So we need to minimize the red areas we see. Once found should be thought to try to eliminate it. Check this option after starting debugging, we can see the following scene on the phone:

Color Blended Layers

Many articles say that setting the control to Opaque = True is the principle of wanting to avoid layer blending, but this tuning is generally less useful. Because the default value of the opaque property of UIView is true, the layer blending does not occur as long as it is not artificially set to transparent. For example, there is no transparent control in the demo.

For Uiimageview, not only does it need to be opaque, its image cannot contain an alpha channel, which is why the third image in the picture is green, and the first two images are red. Since I have almost no understanding of PS and images, I am not able to demonstrate how to eliminate these images in red. I looked for a beautiful woman's avatar from the internet to illustrate that the nature of the image itself might have an impact on the results, so if you're sure your code is fine and there's a layer mix, contact the artist or the background to resolve it.

Personally think that more important than the opaque attribute is the BackgroundColor property, if not set this property, the control is still considered transparent, so the first optimization we do is to add a line of code in the Init method of the Customtablecell class:

Label.backgroundcolor = Uicolor.whitecolor ()

Although this line of code cannot be seen by the naked eye on a white background, we can see that the label's red disappears after re-commissioning. It is also because of the background color of the attention, it becomes the impact of sliding performance of the first killer.

PS: If the label text has Chinese, there will still be layer blending, this is because at this time the label more than a sublayer, if there is a good solution welcome to tell me.

Rasterization

Rasterization is the pre-rendering of a layer into a bitmap (bitmap), which is then added to the cache. If you cache the static content that consumes resources as a result of the shadow effect, you can achieve a certain amplitude performance gain. This line of code in the demo represents the layer rasterization of the label:

Label.layer.shouldRasterize = True

Instrument, the second debug option is "Color Hits Green and Misses red", which means that if the hit cache is shown as green, otherwise it will appear red, and the more green the better, the less red the better. After checking this option we see the following scenario:

Color Hits Green and Misses Red

The core of Rasterization lies in the idea of caching. We can find the following interesting phenomena in our own hands:

    • When the top and bottom of the small amplitude sliding, has been green

    • Swipe up and down, the new label starts with red and then turns green

    • If you rest for a second, it turns red when you start sliding.

This is because the layer is rasterized and rendered as a bitmap in the cache. When the screen slides, we read it directly from the cache without having to render, so we see green. When a new label appears, there is no bitmap for this label in the cache, so it becomes red. 3rd, the object in the cache is valid for only 100ms, that is, if it is not used within 0.1s, it is automatically cleared from the cache. That's why you stay a little longer and then swipe to see red.

The raster caching mechanism is a double-edged sword, and it is possible to consume more time by writing to the cache before reading it. Rasterization is therefore only suitable for more complex, static effects. Through the debugging of instrument, it is found that the use of rasterization is often the case of Miss Cache, if there is no special need to turn off rasterization, so we do the second optimization is to comment out the following line of code:

Label.layer.shouldRasterize = True

Rasterization can cause off-screen rendering, which is a bit later.

Color format

The layout of a pixel in memory is not the same as how it is stored on disk. Consider a simple scenario in which each image has four values of R, G, B, and alpha, and each value occupies 1 bytes, so each pixel occupies 4 bytes of memory space. A picture of 1920*1080 (IPhone6 Plus resolution) has a total of 2,073,600 pixels, thus occupying more than 8Mb of memory. But a picture of a PNG or JPEG format with the same resolution will generally not be this big. This is because JPEG makes a very complex and reversible conversion of pixel data.

When we open a JPEG image, the CPU will perform a series of operations to extract the JPEG image into pixel data. Obviously this work will take a lot of time, so it should not be done while sliding, we should deal with the picture beforehand. Borrow a page of PPT on WWDC to illustrate:

Show process

Commit transaction and Decode are performed within the same frame, and if the two operations take longer than 16.67s,draw calls, they are deferred to the next frame, resulting in a decrease in FPS values. The following is a detailed procedure for COMMIT transaction:

Decoding and Conversion

In the third step of prepare, the CPU mainly handles two things:

    1. Extract the image from a PNG or JPEG format and get the pixel data.

    2. If the GPU does not support this variety of colors, the CPU needs to format the conversion.

For example, there are some images downloaded from the network in the application, and the GPU does not support this format, which requires the CPU to pre-format the conversion. The third option, "Color Copied Images", is used to detect this real-time format conversion and, if there is one, marks the picture as blue.

Unfortunately, I don't know much about the format of the picture, I don't use the tools, and I don't have the ability to simulate a scenario that triggers this option. We want to keep in mind that if a picture is flagged as blue when debugging, there are some problems with the picture format.

Picture size

The fourth option uses a few scenarios, and we'll look directly at the fifth option "Color misaligned Images". It indicates that a picture is marked yellow if it needs to be scaled, or purple if there is no pixel alignment. Tick on this option and debug, you can see the following scenario:

Picture Zoom

In the demo, each uiimageview size is 180x180, and only the second picture has a pixel size of 360x360. So in addition to the second picture, all other images need to be scaled. The scale of the picture takes time, so we want to be as sure as possible whether it's local or from the Web or the size of the image to be consistent with its frame.

The third optimization is to adjust the pixel size of all pictures to avoid unnecessary scaling.

Off-screen rendering

Off-screen rendering means that rendering takes place outside the screen, which you might think is a nonsense. To really explain what is off-screen rendering, let's take a look at the normal render pass (Render-pass):

Normal Render Channel

First, OpenGL submits a command to the commands buffer, then the GPU starts rendering, and the rendering results are placed in render Buffer, which is the normal rendering process. However, there are some complex effects that cannot render the result directly, it requires a step-up rendering to be combined at the end, such as adding a mask (mask):

Off-screen rendering

In the first two render channels, the GPU gets the rendering results for textures (texture, that is, the camera icon) and layer (blue masks). However, these two render results are not directly placed in the render buffer, which means that this is off-screen rendering. Until the third render pass, the two are combined into a render buffer. Off-screen rendering means that the rendered result is temporarily saved, and so on and then taken out, so it is more resource-intensive than normal rendering.

The sixth option, "Color offscreen-rendered Yellow", marks the place where you want the off-screen rendering to be yellow, and in most cases we need to avoid the appearance of yellow as much as possible. Off-screen rendering may be triggered automatically, or it can be triggered manually. The following conditions may cause the off-screen rendering to be triggered:

    1. Overriding the DrawRect method

    2. Mask or Shadow (Layer.maskstobounds, layer.shadow*), the blur effect is also a mask

    3. Layer.shouldrasterize = True

The first two will automatically trigger off-screen rendering, and the third way is to manually turn off-screen rendering.

Start debugging and Tick "Color offscreen-rendered Yellow" To see a scenario like this:

Off-screen rendering

If you do not perform the second step optimization, you will find that the label is also yellow. You can see that Tabbar and StatusBar are also yellow because they use a blur effect. The picture is also yellow, which means that it has also been rendered off-screen, after observing the source of the main reason is that it uses the shadow, next we make a fourth optimization, in the shadow effect of the four lines of code to add a line below:

ImgView.layer.shadowPath = Uibezierpath (rect:imgView.bounds). Cgpath

This line of code makes the shadow path, if not manually specified, the Core animation will automatically calculate, which will trigger off-screen rendering. If you specify a shadow path, you can eliminate the calculation, thus avoiding off-screen rendering.

Setting Cornerradius itself does not cause off-screen rendering, but many times it also needs to be used with layer.maskstobounds = True. Based on the previous summary, setting Maskstobounds will cause off-screen rendering. The solution is to avoid setting fillets when sliding as much as possible, and if you must set rounded corners, you can use rasterization techniques to cache the fillets:

Set Fillet label.layer.masksToBounds = Truelabel.layer.cornerRadius = 8label.layer.shouldrasterize = Truelabel.layer.rasterizationScale = Layer.contentsscale

Quick Path

Remember that the last step in the off-screen rendering and rendering path is to combine the previous paths together. If this combination process can be done by the CPU, the GPU will be much less work. This technique may be used in drawing maps.

The seventh option, "Color compositing Fast-path Blue", is used to mark the path drawn by the hardware, and the more blue the better.

Change area

When refreshing the view, we should minimize the areas that need to be redrawn. The eighth option, Flash updated regions, should not be redrawn for content that has not changed to mark the area where the redraw occurred. A typical example is the clock application of the system, most of the time only the area showing the second hand needs to be redrawn:

Redraw Area

Summarize

If you do this step-by-step, I think there will be some benefits. However, learning without thinking is a myth, but thinking without learning is dangerous. After hands-on practice or should be summarized refining, optimization of sliding performance mainly involves three aspects:

Avoid layer blending

    • Ensure that the opaque property of the control is set to true to ensure that the backgroundcolor and parent view colors are consistent and opaque.

    • If there is no special need, do not set an alpha value below 1.

    • Make sure the uiimage does not have an alpha channel.

Avoid temporary conversions

    • Make sure the picture is the same size as the frame and do not scale the picture while sliding.

    • Make sure that the picture color format is supported by the GPU, avoiding CPU switching.

Use off-screen rendering with caution

    • Most of the time off-screen rendering can affect performance.

    • Overriding the DrawRect method, setting fillets, shadows, blur effects, and rasterization will result in off-screen rendering.

    • Set the shadow effect to add a shadow path.

    • If the fillet effect is required when sliding, turn on rasterization.

Actual combat

The demo of this article can be downloaded on my github and then experience the optimization process one step at a pace. But after all, the demo is deliberately set up an environment, I will be in my own copy of the simple book app to constantly optimize the actual combat, welcome to learn to communicate together.

Resources:

    • Draw pixel to screen, original: Getting Pixels onto the screens

    • Advanced Graphics and animations for IOS Apps: This is the 2014 WWDC Session 419, it is strongly recommended to see it again.

    • How to properly write a good interface

    • Mastering UIKit Performance

There are some high-quality questions and answers:

    • What triggers "color Copied Images" and "Color Hits Green and Misses Red" in Instruments?

    • UILabel is marked as red when Color blended Layers is selected

    • What triggers offscreen rendering, blending and layoutsubviews in IOS?


Uikit Performance Tuning Practical explanation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.