preface

This article is a solution to the tableView fast scrolling caused by the drop frame scheme, if there is a better idea can be pointed out.

This article corresponds to the Github link

This paper refers to and learns the link of YY’s article and the link of this asynchronous drawing cell project. Before reading this article, please at least finish reading this article by YY seniors!

solution

The overall idea is to calculate ahead of time, reduce the amount of calculation in space, efficient use of CPU resources!

  • 1 don’t useAutoLayout, direct useFramelayout
  • 2 Reduce the number of controls
  • Do not use off-screen rendering for things like rounded corners, but draw them directly
  • 4 Use the image of the url asynchronously requestedCALayerdraw
  • 5 Use other controlsasynchronousDraw to an image and return to the main thread to display the image
  • Control the asynchronous drawing threadThe number ofBecause a lot of thread switching is actually a very resource-intensive process
  • Provides a mechanism to undraw when fast scrolling
  • 8 other possible optimizations are not used in this paper, welcome to add

1 don’t useAutoLayout, direct useFramelayout

Generally, in the MVC tableView drawing, the data source agent will pass the Model to the cell, and then calculate the corresponding Frame display data of AutoLayout. We can advance the calculation, calculate the layout,cell height and display content when obtaining data, and use them directly in the rendering All right. The idea is similar to the CELL VM in MVVM, except that the “VM” is responsible for calculating the location of data and displaying content.

See CellLayout in demo for an example:

2 Reduce the number of controls

My approach is to use CALayer for all images except those that need to be loaded asynchronously, so that there is no hierarchy calculation when rendering.

Do not use off-screen rendering for things like rounded corners, but draw them directly

Draw it directly using CGContext, don’t render it out of screen, it is very performance consuming!

4 Use the image of the url asynchronously requestedCALayerdraw

The images here are just for display, so it is a good idea to use CALayer which consumes less resources. In addition, YYKit provides a method similar to SDWebimage for CALayer to load images asynchronously. The difference is that the number of concurrent threads opened is limited during loading, so that a large number of lines will not be opened Process and cause a waste of resources.

5 Use other controlsasynchronousDraw to an image and return to the main thread to display the image

This step is the most core step in this optimization plan, using the CPU’s multi-core advantage, the control should have been shown to do an asynchronous rendering, and finally draw back to the main line for rendering, here only intercept part of the key code, I will delete some other repetitive actions. This is enough to guarantee 60 frames on the iPhone6, but the optimizations below are just to make it better.

Control the asynchronous drawing threadThe number ofBecause a lot of thread switching is actually a very resource-intensive process

This step was mentioned in the url image asynchronously, but I’m trying to control the number of asynchronously drawing threads, which is equal to the number of cores in the CPU, for example, A11 is given 6 threads.

Provides a mechanism to undraw when fast scrolling

Here use a global variable to control, we each create a control will determine the BOOL value, if you don’t need to draw the already, so that he will be Return, so you run on some performance low mobile phone this Demo, slide in very quick will see that some cell is empty, this means that he has been in the process of drawing It was stopped. This may not be very interactive, and we’ll provide a solution in Article 8.

8 Other optimizations that could be used are not used in this article

We can use a shell for fast scrolling, such as this effect

The code and ideas are roughly as follows, but I didn’t write it here because I didn’t have relevant materials

Afterword.

Current knowledge can only optimize here for a while, have any good plan welcome pointed out that our usual optimization also absolutely not to do this, but should write first, reuse some performance optimization tools on the properties of some local optimization step by step, I’m here only to learn and do a demo.

Looking at the efficiency problem here, there is no doubt that without special requirements, the obvious development speed and maintenance of the project using AutoLayout is higher than my practice, so the specific way to do depends on the choice.

If you want to optimize the rendering, you probably have to use Metal or OpegnGL ES to do it. After iOS11, rendering is all Metal.