[iOS] off-screen rendering optimization

Source: Internet
Author: User
Tags transparent color transparent image uikit



Original link: https://mp.weixin.qq.com/s?__biz=MjM5NTIyNTUyMQ==&mid=2709544818&idx=1&sn= 62d0d2e9a363d250beb2d6887dca54b3&scene=0&key= B28b03434249256bb3a6b7bd2f2cbe21550293fa9af7ff8669e50331f9be4207e196edd9757d3c09338a394b4dfefce6&ascene=1 &uin=mti5nzgymda4mq%3d%3d&devicetype=windows-qqbrowser&version=61030003&pass_ticket= Uesqmgu0oh1ernqhdxq8d%2fyfcafsng78ul0wb3obpm16ncviixx7gxugjtlq5kj1



Author Seedante is a low-key person, only willing to reveal his github:https://github.com/seedante





Off-screen rendering (offscreen render)


Objc.io produced by Getting Pixels onto the translation version of the screen to draw pixels to the onscreen should be the most important to the concept of off-screen rendering of the most important article. The article mentions that "compositing a layer directly into a frame's buffer (on the screen) is much cheaper than creating an out-of-screen buffer, then rendering it into a texture, and finally rendering the result into the buffer of the frame." Because this involves two of expensive environment transformations (converting the environment to an out-of-screen buffer, and then converting the environment to the frame buffer). "After triggering off-screen rendering, this conversion occurs at each frame, which can seriously affect the frame rate if there is a large amount of off-screen rendering occurring during the scrolling of the interface."



Official public information on the off-screen rendering information is the first in the 2011 WWDC, in several sessions are mentioned to avoid triggering off-screen rendering effect, including: Mask, shadow, group opacity, Edge antialiasing.



It should have originated from an English developer: using the drawing API in the Core Graphics would also trigger off-screen rendering, such as rewritingdrawRect:.
It is unclear why a few years ago such an understanding was created. In WWDC 2011:understanding UIKit Rendering This session demonstrates "core Animation instruments" using "color offscreen-renderd yellow" selection Word detects off-screen rendering, and the WWDC 2014:advanced Graphics and animations for IOS Apps also specifically demonstrate this tool.






Designing for Ios:graphics & Performance This article also mentions the use of the Core Graphics API to trigger off-screen rendering, which leads to Andy Matuschak, the Apple IOS 4.1-8 period Uik It group members, one of WWDC 2011:understanding UIKit Rendering Speakers, reply to this view, the main meaning is: "core Graphics drawing API does trigger off-screen rendering, but not the kind of GPU off-screen rendering. Using the Core Graphics drawing API is performed on the CPU, triggering a CPU version of off-screen rendering. 」



This article takes "color Offscreen-renderd yellow" as the standard for triggering off-screen rendering, unless there is the behavior that the standard cannot detect to trigger off-screen rendering. Then the Core Graphics API will not trigger off-screen rendering, such as rewritingdrawRect:, and in addition to the above four effects will trigger off-screen rendering, using the system-provided fillet effect will also trigger off-screen rendering, such as:


view.layer.cornerRadius = 5view.layer.masksToBounds = true


Fillet optimization The previous period of time on the meager brush for a good while, do not want to join in the fun, but this topic must be told.



Before you begin, lay the groundwork for something.


The relationship between UIView and Calayer


The relationship between Layers and views are interpreted very carefully but too verbose, in short, UIView is a package for calayer.






From WWDC 2012:ios App performance:graphics and animations



Calayer is responsible for displaying content,contentsUIView providing it with content, and dealing with events such as touch, participating in the response chain. The structure of the Calayer is as follows, derived from Layers having their Own Background and Border:






Calayer has three visual elements, and the middlecontentsattribute is declared like this:var contents: AnyObject?, in fact, it must be aCGImageability to display.



When usinglet view = UIView()generate a View object and added to the screen, from the structure of the calayer can be known, the view of the three visual elements of the layer: emptycontents, the background color is empty (transparent color), the foreground box width of 0 foreground box, this view from the visual see nothing. Calayer documentation The first sentence is: "the Calayer class manages image-based content and allows you to perform animations on that Content."uivi The display content of EW is largely a picture (cgimage).


Uiimageview


Since the Calayer property is directlycontentsassigned to a valueCGImagecan display the picture, so Uiimageview was born smoothly Cheng Zhang. In fact, UIImage is a lightweight package for cgimage (or ciimage). Remember when I first contacted IOS, I do not understand the difference between the two, someone said to me, did not expect the source is here:






From WWDC 2012:ios App performance:graphics and animations



UIKit and the core graphics framework are very close, UIKit theCGclass with the prefix attribute is basically the package corresponding to the object in the core graphics frame, the drawing function in UIKit is also the encapsulation of the core graphics drawing API. Drawing with Quartz and UIKit lists these correspondence. The content of the interface is mainly image and text, how is the text displayed? It is also drawn using the Core Graphics framework.



Next, formally start the topic of this article.


Roundedcorner


To set rounded corners:


view.layer.cornerRadius = 5


What does this line of code do? Description ofcornerRadiusthe properties in the document:


Setting the radius to a value greater than 0.0 causes the layer to begin drawing rounded corners on its background. By default, the corner radius does does not apply to the image in the layer's contents property; It applies only to the background color and border of the layer. However, setting the Maskstobounds property to YES causes the content to being clipped to the rounded corners.


It is clear that only the foreground frame and the background color work, and then see the structure of the calayer, ifcontentsthere is content or the background of the content is not transparent, but also need to get a corner out of this part, or the result of the synthesis is not rounded, so it is to be modifiedmasksToBoundstotrue(in UIView The corresponding setting on theclipsToBoundsIB is the "clip subiews" option). A few days ago. Rounded Corner Optimization Article 2 points out that the change to instead of the modification is themasksToBoundstruereason forcornerRadiustriggering off-screen rendering, but if "color offscreen-renderd yellow"is a standard feature, these two properties are not the cause of the off-screen rendering when they act alone, they are bothmasksToBounds = true, cornerRadius>0.



The system fillet needs to be cropped in the middle of the layer, which is thecontentsimpact of cutting work and off-screen rendering on performance which accounts for a large proportion? I have a little doubt about it. While cropping and off-screen rendering cannot be split at the system fillet, it is possible to independently test the performance impact of the cropping effort. The frame rate provided by the Demo in the quick scrolling below, using an article on the optimized fillet mentioned above, validates the test on this basis:






The number of brackets in the figure represents the number of rounded corners in the same screen when scrolling. At the same time, the effect of the fillet radius on the performance is tested, and there is nocornerRadiusdifference between 0.1 and 10 respectively. When using "color offscreen-renderd yellow" to detect, only the fillet part will have the yellow feature, socornerRadius = 0.1when the basic observation is not, if youcornerRadiusmasksToBoundscan trigger off-screen rendering with doubt, the contrast frame rate will know.



The optimization scheme in this Demo is to redraw the fillet, and the author gives his test results on the IPhone 6, which is very good. It is strange that the demo does not have the work of drawing rounded corners in the background, the article does not explain this, but this demo in my years of service on the IPad Mini 1 (IOS 9.3.1) running results are not satisfactory, obviously should be placed in the background redraw and then switch to the main thread settings content. To do a comparative test, the foreground fillet: the main thread to draw the fillet (the method of optimization of the demo), Background fillet: The original demo drawing operation to the background thread and then switch to the main thread, the number of the same screen fillet is 24, the comparison results:






The foreground fillet performance is slightly better than the system fillet, the background fillet performance and no rounded angle flat. After testing,masksToBounds=trueandcornerRadius>0in a separate role in the performance of the basic no impact (for no rounded corners, foreground fillet and background fillet), and alone can not observe the off-screen rendering of the yellow features, that is, only the system fillet triggered off-screen rendering.



Compared with the above test results, it is necessary to conclude that "in the system fillet (blocking the main thread) clipping is the main factor affecting performance, the blame should not be off-screen rendering to back." "The conclusion came. When there is a problem with view performance, be aware that the bottleneck is on the CPU or GPU, using the GPU Driver Instruments to detect. The number of same-screen fillets in the following tests is around 24:






System fillet: Low frame rate, low CPU utilization, high GPU utilization






Foreground fillet: Frame rate is slightly better than above, unstable, CPU utilization fluctuation is very big, peak near 100%, trough below 20%, GPU utilization is very low



Background fillet: Very good frame rate, very high CPU utilization, peak more than 120%, trough below 10%, GPU utilization is very low



Brutally beaten face! It is a bit surprising that the CPU usage of the manual fillet is as great as the rounded corners. When redrawing the fillet, the drawing work is done by the CPU, which may become a performance bottleneck, the GPU is a bottleneck in the system fillet, because the off-screen rendering and my so-called cutting work can not be separated, before trying to use a self-drawn fillet in vain to prove that the system rounded corners of the work is to affect the performance of the main cause of



Mastering UIKit Performance Describes the example of a fillet when off-screen rendering, the code he gives does not draw a fillet in the background, and he says that the code that draws the fillet is only executed once (it should be designed in practice, only once, Subsequent direct use of the redraw result), but from the code to look at the drawing code can not be executed only once (after all, the Demo, without optimization, and actually become the same as the system fillet, scrolling every frame is redrawn), which becomes the main thread of the manual fillet, optimization efficiency is not high, and the frame rate from the last post does not reach the conclusion that the high frame rate and stability. Since this article did not develop the source code, it is impossible to detect the differences. His test hardware is the iphone 4 (IOS 7.1.1), and my IPad mini 1 generation and the iphone 4 two years, the above Demo test hardware is the iphone 6, and 2 years, considering the difference in hardware performance, redrawing the fillet should be placed in the background is the best solution.


Offscreenrenderdemo


There are several other effects that need to be tested, so you still have to write a demo: Offscreenrenderdemo, which includes all the effects demonstrated in this article and the optimization scheme. Test Demo or the same, TableView with the image and text, long so, the next effect test is mainly concentrated on the left side of the two uiimageview, the dimensions are (three, three), the cell height of 100.






The test environment is:


    • IPad Mini 1st generation with IOS 9.3.1

    • Xcode 7.3 with Swift 2.2

    • OS X 10.11.4


In the Demo to achieve the optimization of the fillet, this topic is not over, the previous section just proves that the interface scrolling process of a large number of off-screen rendering is indeed the frame rate killer. Then put the map to occupy a special place, the next table to present the data, the data is my visual calculation, there will be errors, but also a single test, but the magnitude is no problem. In the following description: The left and right represents a floating around a value, the following representatives are close to a certain value, rarely more than, the above represents the vast majority of a value above, but more than a small margin.



Benchmark performance of Offscreenrenderdemo:


number of round corners of the same screen system Average FPS Average GPU Utilization CPU Utilization
No 57 or more 10% or less 20%~40%
10 Around 44 80% or more 10%~50%
20 Around 35 90% or less 10%~40%


CPU utilization is difficult to use the average value to present, from above also can see the CPU utilization is cyclical fluctuation, this is the characteristic of this kind of Demo, which makes it difficult to compare the CPU utilization in two Tests. The range of fluctuations shown in the table above can only be used as a reference to whether the CPU is a performance bottleneck, and cannot be compared with other tests. The sample interval for the CPU in the above figure is 1s for the 1ms,fps and GPU utilization, these are the default values. If you want to increase the CPU sampling interval time to form a similar histogram, basically meaningless, the data here is cumulative utilization, a little attention to see more than 100%. The bottleneck of the effect of triggering off-screen rendering is mainly the low utilization of the gpu,cpu, and of course, the view performance is related to both the CPU and the GPU, and the later effect will explain the CPU utilization.



In my Demo, the background draw rounded corners from needless to say and without any effect of the performance is very close to the main thread to draw a rounded corner performance is only slightly reduced. This is very different from the previous Demo, the results shown in the same screen fillet number 24, the average frame rate of about 40, fixed to 20 tests once, the average frame rate still hovering around 40. My demo CPU utilization is not as dramatic as the previous demo when the main thread and background threads draw fillets. Because of the differences in the code, these conditions are difficult to explain, but once again prove that, for high frame rate, background rendering is the optimal solution.



Most of the schemes to earn stars have been redrawn with rounded corners, and there are many ways to redraw them. An optimization scheme for the actual redrawing of rounded corners it is necessary to consider redrawing the image to a rounded image as a copy, should it be cached? A. After the first redraw, the rounded images are cached on disk, the second load uses the cached fillet image directly, and B. Stored directly in memory, is obviously not a good choice when memory is tight; C. Do not cache, and the system fillet, every time to redraw, wasting power.



With so much to say, the redraw scheme has no advantage over other optimization schemes. To see other scenarios:


    1. If you do not need to make a rounded image of an external source, it is most convenient for the designer to draw a rounded picture directly.

    2. Blend layers: Overlay A partially transparent view on the view where you want to add rounded corners, obscuring only the fillet portion. This is what the Vvebo Weibo client does, and the part of the background that obscures it best is the same as the surrounding background. More than one layer increases the amount of work for the composition, but this effort is negligible compared to off-screen rendering, with no effect on performance in any way. The image below the left is used to create the mask image of the round head in the Vvebo, in fact, the basic requirement is to create a round head, the ordinary fillet mask needs the left two, the left three is a universal type. If the overlay views are the same, you can load the matte picture only once to reduce memory consumption.





In addition to using software to save the project, it is very easy to draw it directly from the code. Even if you're not familiar with the Core graphics API, it's easy to find the code to redraw the rounded corners, but it's a little tricky to draw the graphic above. It's better to try this thing: in a setopaque = falseof Cgcontext, set the fill color and then surround it with two Bezier curves, and finally export the image from the drawing environment. I wrote a function to generate the area fillet matte Image: Draw a transparent image.



How do I implement rounded corners on a text view class? The text view is mainly these three categories: UILabel, Uitextfield, Uitextview. The Uitextfield class comes with rounded shape, UILabel and Uitextview to show that the fillet needs to be different from the surrounding background color. To achieve a low-cost fillet on UILabel and Uitextview (without triggering off-screen rendering), you need to ensure that the layer'scontentsrendered transparent background color, the layer of the text view classcontentsis transparent by default (characters are drawn and displayed in this transparent environment). At this point only need to set the layerbackgroundColor, plus youcornerRadiuscan get it done. However, the behavior set on the UILabel isbackgroundColorchanged, not the background color of the set layer, but thecontentsbackground color to set, Uitextview does not change this point, so on the UILabel to achieve the fillet to do this:


//不要这么做:label.backgroundColor = aColor 以及不要在 IB 里为 label 设置背景色label.layer.backgroundColor = aColorlabel.layer.cornerRadius = 5
Shadow


Shadow Properties shows how shadows are combined with the view itself:






The shadow is directly synthesized below the view, and there is no more view in the view structure. When no shadow path is specified, the shadow is extended along the non-transparent portion of the view, and shadows are present when at least one of the three visual elements of Calayer exists.



The shadow must be guaranteed to be a layermasksToBounds = false, so the shadow is incompatible with the system fillet. But notice that the impact on performance is still not visually visible. This usually implements a shadow:


let imageViewLayer = avatorView.layerimageViewLayer.shadowColor = UIColor.blackColor().CGColorimageViewLayer.shadowOpacity = 1.0 //此参数默认为0,即阴影不显示imageViewLayer.shadowRadius = 2.0 //给阴影加上圆角,对性能无明显影响imageViewLayer.shadowOffset = CGSize(width: 5, height: 5)//设定路径:与视图的边界相同let path = UIBezierPath(rect: cell.imageView.bounds)imageViewLayer.shadowPath = path.CGPath//路径默认为 nil


In Offscreenrenderdemo, only the shadow is turned on (no path specified, 10 or more of the same screen) when scrolling, the frame rate decreases significantly, the yellow feature of off-screen rendering is detected, and the off-screen rendering feature disappears when a simple path with the same boundary is specified, and the frame rate returns to normal.



Test results:


conditions number of Shadow in the same screen Average FPS Average GPU Utilization off-screen rendering features
Shadowpath = Nil 10 Around 38 Around 73% Yes
Shadowpath! = Nil 10 56 or more 15% or less No
Shadowpath = Nil 20 Around 22 Around 80% Yes
Shadowpath! = Nil 20 56 or more 20% or less No


No significant change in CPU utilization before and after specifying a path for the shadow, most of the time under 50%, cannot determine whether the set path increases the burden on the CPU. It's going to be a calayer. TheshadowPathdefault value is nil, however the effect is consistent with the view boundary path, and if Calayer adds the same path as the boundary by default, this problem can be avoided altogether.



In addition to specifying a path, there are ways to achieve good performance shadowing: Use the rounded corners to refine the blend layer to simulate the effect of the shadow: A view with the same effect below the view to which you want to add the shadow level, and a core graphics to draw the shadow, but unless it's a last resort, no one wants to touch the core graphics. Api. In terms of implementation costs, it is not as convenient as specifying a path. These two methods to achieve a simple shape of the shadow more convenient, than the left and middle of the effect, facing the right shadow effect is not good, with the method of the specified path is also more trouble, fortunately, there is more simple and convenient optimization method, see the section of the finale.


Mask


The mask effect is very similar to a blend layer, except that when you use the same matte image, mask and the blend layer have the opposite effect, using the reverse content matte in the Demo to achieve rounded corners. Implement the Mask effect using the Calayerlayerproperty, you can use the UIView property above IOS 8maskView. Code:


if #available(iOS 8.0, *) {    avatorView.maskView = UIImageView(image: maskImage)} else {    let maskLayer = CALayer()    maskLayer.frame = avatorView.bounds    maskLayer.contents = maskImage?.CGImage    avatorView.layer.mask = maskLayer            }


If all maskimage are the same, it is enough to use a maskimage, otherwise a new UIImage will be a performance hazard each time it is generated. Note: You can use the same maskimage, but you cannot use the same maskview, or you will only have a mask effect.



Test results:


masks in the same screen
number of Average FPS Average GPU Utilization off-screen rendering features
10 Around 55 Around 60% Yes
20 Around 37 Around 75% Yes


Does the transparent area of the maskimage affect performance? The rough test has no effect, at least in the Demo size (80, 80) This level has no noticeable effect on the dimensions.



The CPU utilization of the two groups of tests was under 50% for most of the time, with no significant difference. Look at the 1th set of data, it is interesting, in the case of the same screen mask number of 10, the performance of almost no impact, although the GPU utilization is a bit high, but also can be fixed, to ensure the smooth rolling; When the mask number increases to 20, GPU usage increases significantly, with a mask number of 10 GPU The utilization rate is already high, the number increases 10, the GPU can't hold up, the rolling frame rate drops very badly. Mask-induced off-screen rendering has a weaker impact on performance than the previous two effects.



The mask effect does not cancel off-screen rendering, using a blend layer method to simulate the mask effect, with no effect on all aspects of performance.



You can also use mask to achieve rounded corners without using a picture, and use Cashapelayer to specify a mixed path.




The same mask effect uses cashapelayer when compared to the direct use of maskimage at a slightly lower frame rate, no significant change in CPU utilization, but also lower GPU utilization.



The WWDC 2014:advanced Graphics and animations for IOS Apps explain the mask rendering process in detail, and honestly it doesn't look as good as compositing two views, but there's no more detail about what the difference is between the two. And according to this session, the system fillet is implemented using mask, but obviously not optimized. In addition this session GPU Driver also called Open GL ES Driver.


Groupopacity


First look at what effect groupopacity is:






Groupopacity refers to the Calayer property, and the UIView property is the same as theallowsGroupOpacityalphaCalayeropacityattribute. When Groupopacity is turned on, the upper limit of the child layer's visual transparency is its parent layeropacity.



The document description for this property:


The default value is read from the Boolean Uiviewgroupopacity property in the main bundle ' s Info.plist file. If no value is found, the default value is YES to apps linked against the IOS 7 SDK or later and no for apps linked again St an earlier SDK.


This feature is enabled by default globally since IOS 7, in order to keep the child view as transparent as its container view.



Groupopacity on off-screen rendering is:layer.opacity != 1.0and has a sub layer or background image.



This trigger condition is not requiredsubLayer.opacity != 1.0and is very easy to meet. However, setting the cell or Cell.contentview property in a view such as TableViewalphais less than 1 and does not detect the yellow feature of off-screen rendering, and there is no significant difference in performance. After finding out: only set TableViewalphaless than 1 o'clock will trigger off-screen rendering, no significant impact on performance; setting the cell'salphaproperties does not affect the overall transparency, only the setting Cell.contentview is valid.



Groupopacity-triggered off-screen rendering can be easily observed in the general Uiviewcontroller view, where you can only guess TableView changed these behaviors.


Edgeantialiasing


After testing, turning on edge antialiasing (rotate view and setlayer.allowsEdgeAntialiasing = true) does not trigger off-screen rendering on iOS 8 and iOS 9, and it may not have any effect on performance, and perhaps this feature has been optimized.


Ultimate Optimization Solution


In addition to Groupopacity and edgeantialiasing, other effect-triggered off-screen rendering will have a serious impact on performance, off-screen rendering really useless? No, off-screen rendering would have been an optimized design. How to make the most of it? The answer is: rasterization. In Offscreenrenderdemo, you only need to do this:


cell.layer.shouldRasterize = truecell.layer.rasterizationScale = cell.layer.contentsScale


shouldRasterize = false, the yellow feature of off-screen rendering is limited to the part of the above that automatically triggers the effect of off-screen rendering,shouldRasterize = trueand after that section and the layer whole (which is the cell as a whole) with the property turned on, there is a yellow feature, so turning on rasterization is manually starting off-screen rendering.



From the previous point of view, off-screen rendering would impose a heavy burden on the GPU, wouldn't it be worse to force the boot? When Rasterization is turned on, the GPU will only synthesize the contents once and then reuse the results of the composite, and the composition will be removed from the cache without the use of 100ms, and more off-screen rendering is generated when the content is updated. For views that do not change in content, off-screen rendering, which has been dragged down, becomes a boost; If the view content is dynamically changing, using this scenario can make performance worse.



The Core Animation Instruments has a "color Hits green and Misses red" option, turn on the rasterization and turn on this option, the green part of the screen indicates that the render cache is available, The red section indicates that no render cache is available. In Offscreenrenderdemo, when Rasterization is turned on for any of these effects, the view that is still in the screen range after scrolling is reused for the cached render results, and you can see that this part is marked green and is about to appear on the screen. Views that are in the scrolling edge range are marked in red.



By default, theshouldRasterizeproperty isfalse. After opening, compare with the original test:


conditions number of round corners of the same screen system Average FPS Average GPU Utilization off-screen rendering features
Shouldrasterize = False 10 Around 44 80% or more Yes
Shouldrasterize = True 10 55 or more 20% or less Yes
Shouldrasterize = False 20 Around 35 90% or less Yes
Shouldrasterize = True 20 Around 55 Around 20% Yes
conditions number of Shadow in the same screen Average FPS Average GPU Utilization off-screen rendering features
Shouldrasterize = False 10 Around 38 Around 73% Yes
Shouldrasterize = True 10 55 or more 30% or less Yes
Shadowpath! = Nil 10 56 or more 15% or less No
Shouldrasterize = False 20 Around 22 Around 80% Yes
Shouldrasterize = True 20 Around 55 40% or less Yes
Shadowpath! = Nil 20 56 or more 20% or less No


At least one default setting is reserved for rasterization and Shadowpath above. The GPU utilization of the rasterization is higher than the specified path.


masks in the same screen
conditions number of Average FPS Average GPU Utilization off-screen rendering features
Shouldrasterize = False 10 Around 55 Around 60% Yes
Shouldrasterize = True 10 55 or more Around 20% Yes
Shouldrasterize = False 20 Around 37 Around 75% Yes
Shouldrasterize = True 20 Around 55 30% or less Yes


Judging from the above data, the optimization effect of rasterization is very effective. For GPUs, the interface can maintain a high frame rate when utilization is below 60%.



As mentioned earlier, if the view content is dynamically changing, using rasterization may make performance worse. Under what circumstances will encounter dynamic content view, can think of only the background download picture after the switch to the main thread set this. To simulate, call thetableView:cellForRowAtIndexPath:following methods in:


func dynamicallyUpdateCell(cell: UITableViewCell){    let number = Int(UInt32(arc4random()) % UInt32(10))    let labelL = cell.viewWithTag(30) as! UILabel    labelL.text = "OffscreenRender" + String(number)           let avatorViewL = cell.viewWithTag(10) as! UIImageView    avatorViewL.layer.cornerRadius = CGFloat(number)    avatorViewL.clipsToBounds = true    let delay = NSTimeInterval(number) * 0.1    performSelector(#selector(TableViewController.dynamicallyUpdateCell(_:)), withObject: cell, afterDelay: delay)}


This code updates the contents of the UILabel and the head fillet radius in a random time, where only half of the views are set. The following is the performance of setting up two avatars and two labels after opening rasterization, where the peak of the GPU is around 50%, the peak of the CPU approaching the peak of 100%,fps is around 55, and the trough is about 20.






No operation in the first 8 seconds after launch, 8-20 seconds scrolling view, 20-32 seconds without operation, 32-42 seconds scrolling view, 42-56 seconds without operation, 00:56~01:12 scrolling view, 01:12~ end no action. In addition to the 20-32 second FPS is a bit abnormally high, others are more regular: FPS is very low in no operation, around 20, CPU full load, GPU utilization is also peak, about 50%; When the view scrolls, the FPS is very high, and the CPU and GPU utilization decreases over 50.



The information you need to know is that the main thread will be delayed when it is busyperformSelector:withObject:afterDelay:, so this method will not run when a touch or view is still scrolling; using "color Hits Green and Misses red" to observe the use of off-screen rendering for cache discovery: GPU The ability to use a cache of portions of the view, rather than having to re-render the entire view every time it is updated, improves rendering efficiency. So when the view does not scroll anddynamicallyUpdateCell:still calls itself, you can see the picture is red and green mottled.



According to the above two pieces of information to analyze performance trends: The application starts 8 seconds after the CPU trend is quite random, intermittent to achieve a higher occupancy rate, this phase of the CPU is a performance bottleneck, FPS is very low. When the view scrolls, because the Performselector does not execute, and the ordinary method call does not havetableView:cellForRowAtIndexPath:two, the CPU utilization is not high, under the function of the rasterization, the GPU utilization is not high, the FPS greatly increases, and when the view stops scrolling, Performselector began to execute, it seems that the accumulation of work to deliberately set the randomness lost, CPU time full load, GPU utilization also increased, and benefit from rasterization, and not to a high point, but due to the full load of the CPU, FPS Reduced to very low.



From the results, the GPU utilization is not always high after opening the rasterization, if the CPU utilization is controlled properly, FPS will not be ugly, much better than expected performance.


Summarize
    1. RoundedcornercornerRadiusdoes not trigger off-screen rendering when specified, only applies to special cases:contentsnil orcontentsdoes not obscure background color fillets;

    2. Shawdow can cancel off-screen rendering by specifying a path;

    3. Mask cannot cancel off-screen rendering;


Effects of the above effects on the same number of scales: Shadow > Roundedcorner > Mask > groupopacity (Fan effect).



There are two ways to avoid triggering off-screen rendering at any given time:


    1. Rasterization: Views that apply to static content, that is, the view that the internal structure and content do not change, are the most balanced in terms of cost and performance for all of the above effects. Even a dynamically changing view, when Rasterization is turned on, can effectively reduce the load on the GPU, but whether or not Instruments data is enabled or seen in Dynamic view.

    2. Avoid off-screen rendering, using other techniques to simulate the effect, a hybrid layer is the best performance, the least energy-consuming general optimization scheme, especially for rounded corer and mask.


Demo:https://github.com/seedante/optimizationforoffscreenrender.git



[iOS] off-screen rendering optimization


Related Article

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.