In the last article, we looked at the iOS rendering loop, the off-screen rendering principle, and the lag principle. In this article, we will explore the detection of lag and how to eliminate it.

Catton’s tests

Caton time ratio

To detect Caton, we can use Instrument’s Animation Hitches to detect Caton.

In Apple’s official advice, the lag time ratio is used to measure the severity of the lag.

If the holdup time within 1s exceeds 10ms, the holdup is serious and needs to be resolved.

Animation Hitches

Next, we first of our UITableView slide to perform a lag analysis, run the App on the real machine, check the results:

The results were particularly poor: there were a lot ofSerious catonA few caton did290ms/s.

Time Profile

We click on the Time Profile to see the function call stack at this point and filter out the system calls

We go to the main thread call stack of our App and look at the percentage of time it’s used

It can be seen from the analysis that there are a lot of time-consuming operations in model.setter methods of cellforRow method, resulting in delay in the submission stage, resulting in lag. You can use this method to analyze the holdup in the commit phase by looking at the function call stack for each holdup in turn.

Show Optimization Opportunities

On the other hand, we can also use Xcode to check the performance of our App. In Xcode 12, click Debug View Hierarchy, and then in the Editor option, By default, Show Optimization Opportunities is checked, and Xcode will help us check for some Optimization suggestions during the running of the App.

We use a cornerRadius with a corner mask and a corner mask. The cornerRadius is a cornerRadius.

Why not mask?

inEditorOptions, selectShow Layers:

Using CAShaperLayer + mask to create rounded corners will result in an off-screen rendering. During the scrolling of the cell, there will be hundreds or thousands of off-screen renderings submitted to the render server, resulting in stuttering.

Color Off-screen Rendered

In the simulator, go to Debug -> Color off-screen Rendered to detect the off-screen Rendered view, which will be marked yellow.

From the simulator, we can see that the container view causes an off-screen rendering.

A list of optimization

The rounded optimization

1. After iOS13, you can use the ApIcornerRadius and cornerCurve of the system.

view.layer.cornerRadius = 22 
view.layer.cornerCurve = .continous
Copy the code

2. For UILabel and UIButton, you can use a cornerRadius directly.

label.layer.cornerRadius = 22
Copy the code

3. Rewrite the view’s -drawRect: method to draw rounded corners using Core Graphic

- (void)drawRect:(CGRect)rect { [super drawRect:rect]; UIBezierPath *p = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:(_bottomLeftRadius?UIRectCornerBottomLeft:0)|(_bottomRightRadius?UIRectCornerBottomRight:0)|(_topLeftR adius?UIRectCornerTopLeft:0)|(_topRightRadius?UIRectCornerTopRight:0) cornerRadii:CGSizeMake(_singleCornerRadius, 0.f)];  CGContextRef c = UIGraphicsGetCurrentContext(); CGContextAddPath(c, p.CGPath); CGContextClosePath(c); CGContextClip(c); CGContextAddRect(c, rect); CGContextSetFillColorWithColor(c, _bgColor.CGColor); CGContextFillPath(c); }Copy the code

This section describes how to transfer GPU operations to cpus to balance GPU and CPU operations.

Data source preloading

After the iOS 10, you can use, can use UITableViewDataSourcePrefetching agent method, the data can be preloaded

func tableView(tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) { let needFetch = indexPaths.contains { $0.section >= self.layoutArray.count - 1 } if needFetch { // 1. Meet the conditions to make a page turn request}}Copy the code

Data source preprocessing

After the network requests the data, it preprocesses the data, putting the initialization logic of NSAttributeString and the data source logic processing in a cross-step thread.

If AutoLayout is not used, the frame of the subview can be calculated during data source preprocessing.

Optimize the cellForRow method

Move events such as the cell’s background color processing and event binding to the willDisplayCell. In the cellforRow method, no logic is done, just a simple assignment.

AutoLayout

If the cell uses an AutoLayout layout, there are two issues to be aware of:

  • 1. The constraint conflict problem should be solved. This error is often reported in dynamic operation of constraint values.

    To solve such problems, we can start from two aspects: 1. Analyze whether constraints are reasonable. 2. You can try changing the Priority of the constraint.

Will attempt to recover by breaking constraint

<NSLayoutConstraint:0x600003b0cc80 DBRadiusView:0x7fb9d80b0e20.bottom == UIImageView:0x7fb9d80b59c0.bottom + 8>
Copy the code
  • 2, to avoidLoss of constraintProblems, avoid incellRepeated in the reuse processRemove the constraintandAdditional constraints

Avoiding View Deletion

If message views are needed, avoid removing the view from the cell and use the Hidden property whenever possible.

Results contrast

Now that we’ve done these optimizations, let’s look at the Cartun distribution

The maximum holdup time ratio is 32.84ms/s. When the list is sliding, there is no high grade holdup, so a relatively ideal state is achieved.

Before and after video:

Before optimization: Youku link

After optimization: Youku link