preface

Short step without thousands of miles, not small streams into rivers and seas. Learning is like rowing upstream; not to advance is to drop back. I’m a hauler who drifts from platform to platform. Study half an hour a day, health and happiness for a lifetime. Today, I will tell you about performance optimization. I don’t know if you can. Nonsense not to say, directly to everyone dry goods, I hope to help you, excellent people have been praised.

A concept

One of the most valuable attributes in performance optimization is FPS:Frames Per Second, which is the screen refresh rate, apple’s iPhone

The recommended refresh rate is 60Hz, which means that the GPU refreshes the screen 60 times per second. Each refresh is a frame, and an FPS is a frame

Refresh how many frames per second. The FPS value of a static page is 0, which is meaningless only when the page is animating or

When sliding, the FPS value is of reference value. The FPS value reflects the smoothness of the page, and slows down below 45

It’s going to be obvious.

Layer Blending:

Each layer is a texture, and all textures are somehow stacked on top of each other. For every pixel on the screen, the GPU needs

Figure out how to mix these textures to get pixel RGB values.

When Sa = 0.5, the RGB value is (0.5, 0, 0). It can be seen that when two calayers that are not completely opaque are overlaid together, the GPU does a lot

This combination of operations, as you do more of these operations and your GPU gets busier, performance will definitely suffer.

Formula:

R = S + D * 1 – Sa

The resulting color is the source color (top texture)+ target color (lower texture)*(1- opacity of the source color).

When Sa = 1 and R = S, the GPU will not do any composition, but will simply copy from this layer, without considering anything below it (because both

Obscured by it), which saves the GPU a considerable amount of work.

First, entry level

1. Use ARC to manage memory

2. Use reuseIdentifier in the right place

3, try to set the views to transparent

4. Avoid large XIBs

5. Do not block the main thread

6. Resize the image in ImageViews. If you want to display an image from a bundle in a UIImageView, you should make sure the image is there

Is the same size as UIImageView. Zooming in and out of images on the fly is expensive, especially when UIImageView is nested in

UIScrollView. If the image is loaded from a remote service, you can’t control the image size, such as adjusting it to a suitable size before downloading

If it’s small, you can download it once it’s done, preferably with background

Thread, scale once, and then use the scaled image in UIImageView.

7. Select the right Collection.

  • Arrays: an ordered set of values. Index lookup is fast, value lookup is slow, and insert/delete is slow.

  • Dictionaries: Store key-value pairs. It’s faster to look it up by keys.

  • Sets: an unordered set of values. Quick to find by value, quick to insert/delete. 8. Enable gzip compression. Apps can rely heavily on server resources, but the problem is that we’re targeting mobile devices, so you can’t count on a good network. One way to reduce documentation is to open Gzip on the server and in your app. This is especially useful for text, which has a higher compression rate.

IOS already supports gzip compression by default in NSURLConnection, as do frameworks like AFNetworking based on it.

Second, the intermediate

1. Reuse and lazy load Views

  • More views means more rendering, which means more CPU and memory consumption for those with a lot of nested views

This is especially true for apps in UIScrollView.

  • The trick we use here is to mimic the actions of UITableView and UICollectionView: instead of creating all subviews at once,

Instead, create them as needed, and when they’re done, put them in a reusable queue. That way, all you have to do is

Create your views when scrolling occurs, avoiding uneconomical memory allocation.

Cache, Cache, Cache!

  • A good rule of thumb is that the cache needs things that are not likely to change but need to be read frequently.

  • What can we cache? Some options are responses from the remote server, images, and even computed results, such as UITableView

High line.

  • NSCache is similar to NSDictionary, except that when the system reclaims memory, it automatically deletes its contents.

3. Weigh rendering methods. Performance depends on keeping bundles at the right size.

4. Handle memory warnings. Remove strong references for caches, image objects, and other objects that can be recreated.

Reuse large overhead objects

Some objects are slow to initialize, such as NSDateFormatter and NSCalendar. However, you will inevitably need to use them,

For example, parsing data from JSON or XML. To avoid the bottleneck of using objects you need to reuse them by adding attributes

Go to your class or create a static variable.

7. Avoid reprocessing data. It is important to use the same data structure on both the server and client sides.

8. Choose the right data format. Parsing JSON is faster than XML, and JSON is usually smaller and easier to transport. It’s official since iOS5

Built-in JSON deserialization is easier to use. But XML also has XML benefits, such as parsing XML using SAX

As with local files, you don’t need to wait until the entire document has been downloaded to parse, as with JSON. When you’re dealing with big data

This greatly reduces memory consumption and increases performance.

9. Set the background image correctly

  • Full screen background, add a UIImageView to the view as a child view

  • Just a small view background, you’ll need to do it with UIColor’s colorWithPatternImage, which will render faster

It doesn’t cost a lot of memory:

Reduce the use of Web features. For better performance you need to tweak your HTML. The first thing to do is to remove as many no

Necessary javascript, avoid using too large a framework. It would be nice to just use native JS. Load as asynchronously as possible such as user behavior statistics scripts

This does not affect javascript expression on the page. Pay attention to the images you use and make sure they fit the size you use.

11. Shadow Path. CoreAnimation has to draw and shadow your graphics in the background before rendering, which is expensive.

Using shadowPath avoids this problem. With shadow Path iOS doesn’t have to calculate how to render every time, it uses

A precomputed path. The problem is that calculating the path by yourself can be difficult in some views, and every time the View’s frame

You need to update the Shadow path whenever it changes.

Optimize the Table View

  • Use reuseIdentifier correctly to reuse cells

  • Try to make all view Opaque, including the cell itself

  • Avoid gradients, zoom, and background selection

  • Cache line height

  • If the actual content in the cell comes from the Web, use asynchronous loading and cache the request results

  • Use shadowPath to draw shadows

  • Reduce the number of subviews

  • Try not to use cellForRowAtIndexPath: if you need to use it, just use – once and then cache the result

  • Use the right data structure to store data

  • Use rowHeight, sectionFooterHeight, and sectionHeaderHeight to set fixed heights, and do not request a delegate

13. Select the correct data store options

  • What’s the problem with NSUserDefaults? While it’s nice and convenient, it only works with small pieces of data, such as simple cloth

Er type setting options, larger you have to consider other ways

  • What about structured files like XML? In general, you need to read the entire file into memory to parse, which is very uneconomical. use

SAX is another tricky thing.

  • NSCoding? Unfortunately, it also needs to read and write files, so it has the same problems.

  • In this scenario, SQLite or Core Data is preferable. With these techniques you can only add with a specific query

Pick up the person you need.

  • SQLite and Core Data are very similar in terms of performance. They differ in how they are used.

  • Core Data represents a Graph Model of an object, but SQLite is a DBMS.

  • Apple recommends using Core Data in general, but if you have a reason not to use it, go for the lower-level SQLite

.

  • If you use SQLite, you can use the FMDB library to simplify SQLite operations so that you don’t have to spend a lot of time learning SQLite

C API.

Senior three,

1. Accelerate startup time. It’s important to open an app quickly, especially when users open it for the first time

Important. What you can do is make it do as many asynchronous tasks as possible, such as loading remote or database data and parsing data. To avoid a

Large XIBs because they are loaded on the main thread. Try to use Storyboards that don’t have this problem! Be sure to set

The standby is disconnected from Xcode to test startup speed

2. Use Autorelease Pool. NSAutoreleasePool is responsible for releasing the autoreleased objects in the block. In general it’s

It’s automatically called by UIKit. But in some cases you need to create it manually. If you create a lot of temporary objects, you’ll find that memory is always there

Decrease until those objects are released. This is because memory is only destroyed when UIKit runs out of autoRelease pools

Release. The message is that you can avoid this behavior by creating temporary objects in your own @Autoreleasepool.

3. Select whether to cache images. There are two common ways to load images from a bundle: using imageNamed and using

Image with Content file, the first one is a little bit more common.

4. Avoid date format conversions. If you’re going to use NSDateFormatter to handle a lot of date formats, be careful. As mentioned earlier

It’s a good practice to reuse NSDateFormatters anytime. If you can control the date format you work with, try to choose it

Unix timestamp. You can easily convert from timestamp to NSDate:

This will be faster than parsing a date string in C! It is important to note that many Web apis are written in microseconds

Form returns a timestamp because this format is easier to use in javascript. Remember to divide by 1000 before dateFromUnixTimestamp

All right.

How do you optimize your code for performance?

  • Use performance analysis tools, including the static Analyze tool, as well as the runtime Profile tool, from the Xcode toolbar

Product->Profile can be launched,

  • For example, test application startup run Time, when clicking on the Time Profiler application to start running. You can get the entire application running

Consumption time distribution and percentage. In order to ensure that data analysis in the unified use of real scenarios need to pay attention to the use of real machine, because this mode

Simulators run on Macs, which tend to have faster cpus than iOS devices.

  • To prevent an app from taking up too much of the system’s resources, Apple engineers working on iOS devised a “watchdog” mechanism. without

In the same scenario, the watchdog monitors application performance. If the running time specified for the scenario is exceeded, the Watchdog forces

Terminate the application process. Developers will see error codes such as 0x8BadF00D in crashlog.

Optimization of the Table View

  • Use reuseIdentifier correctly to reuse cells

  • Try to make all view Opaque, including the cell itself

  • If the actual content in the cell comes from the Web, use asynchronous loading and cache the request results

Reduce the number of subviews

  • Try not to use cellForRowAtIndexPath: if you need to use it, just use it once and then cache the result

  • Use rowHeight, sectionFooterHeight and sectionHeaderHeight to set fixed heights, do not request delegateUIImage

Loading picture performance problem

  • ImagedNamed initialization

  • ImageWithContentsOfFile initialization

  • ImageNamed caches the image in memory by default after loading the image successfully. This method looks up the image in the system cache with a specified name and

Returns a picture object. If no corresponding image object is found in the cache, the image is loaded from the specified location and the object is cached and returned

Return to this picture object.

  • Image with Content file only loads images, not caches.

  • Load a large image and use it once, using image with Content file is best, so the CPU doesn’t need to cache to save time.

  • When programming scenarios, it should be differentiated according to actual application scenarios. Although UIimage is small, there will be some problems when using more elements

Highlights.

  • Do not do time-consuming operations in viewWillAppear: viewWillAppear: called before the view is displayed, for efficiency reasons

The method should not deal with complex and time-consuming operations; In this method, simple things like setting the display properties of the view, like the background color,

Font, etc. Otherwise, it will be obvious that the view is stalling or delayed.

  • In the right place to use reuseIdentifier: table view with a tableView: cellForRowAtIndexPath: distribution of rows

Cells, its data should be reused from the UITableViewCell.

  • Try to make views transparent: If you have transparent views you should set their opaque property to YES. The system use

An optimal way to render these views. This simple property can be set either in IB or in code.

  • Avoid large XIBs: Simply configure a separate XIB for each Controller, with a View if possible

The Controller view hierarchy is split into separate XIBs, and when you load a NIB that references an image or sound resource,

The NIB load code writes the image and sound files into memory.

  • Do not block the main thread: Never overload the main thread. Because UIKit does all the work on the main thread, rendering, managing

Touch responses, input responses and so on are all done on it, and most of the things that block the main process are things that your app is doing that involve reading and writing

I/O operations on external resources, such as storage or network.

Facebook startup time optimization

  1. Thin request dependency

2.UDP startup requests are cached first

3. Queue serialization processes the start response

Fourth, rasterization

Rasterization is the process of converting geometric data into pixels after a series of transformations and presenting them on the display device. The essence of rasterization is coordinate transformation and geometric discretization

When we’re using UITableView and UICollectionView, we often have the same Cell style, so we can use this

Three properties improve performance:

5. How to check memory leaks?

There are several ways I know of so far

  • Memory Leaks

  • Alloctions

  • Analyse

  • Debug Memory Graph

  • MLeaksFinder

The leaked memory includes the following two types:

  • Lak Memory is the Memory leaked by forgetting to Release.

  • Abandon Memory is a kind of Memory that can’t be freed and is referenced in a loop.

The above mentioned five ways, in fact, the first four are more troublesome, need to constantly debug the operation, the fifth is Tencent reading team produced, the effect

Better

Six, how to draw a high performance rounded corner

First, the above method is not desirable, will trigger the off-screen rendering.

  • If you can solve the problem with only a cornerRadius, you don’t need to optimize.

  • If you must set masksToBounds, refer to the number of rounded views, or consider not optimizing if the number is small (only a few on a page).

  • The rounded corners of UIImageView can be achieved by directly capturing the image, and the rounded corners of other views can be achieved by Core Graphics drawing rounded rectangles.

How to improve the smoothness of tableView?

In essence, the CPU and GPU work is reduced to improve performance from these two aspects.

  • CPU: object creation and destruction, object property adjustment, layout calculation, text calculation and typesetting, image format conversion and decoding,

Image drawing

  • GPU: Texture rendering

Caton optimization at the CPU level

  • Try to use lightweight objects, such as CALayer instead of UIView, for places that don’t handle events

  • Don’t make frequent calls to UIView properties such as frame, bounds, Transform, etc., and minimize unnecessary changes

  • Try to calculate the layout in advance, adjust the corresponding attributes at one time if necessary, do not modify the attributes more than once

  • Autolayout consumes more CPU resources than setting the frame directly

  • The image size should be exactly the same as the UIImageView size

  • Control the maximum number of concurrent threads

  • Try to put time-consuming operations into child threads

  • Text processing (size calculation, drawing)

  • Image processing (decoding, rendering)

Caton optimization at the GPU level

  • Try to avoid the display of a large number of pictures in a short period of time, as far as possible to display a composite of multiple pictures

  • The maximum texture size that GPU can process is 4096×4096. Once this size is exceeded, CPU resources will be occupied for processing, so

The texture should not exceed this size

  • Minimize the number of views and levels

  • Reduce transparent views (alpha<1) and set Opaque to YES for opaque views

  • Try to avoid off-screen rendering

1. Pre-typesetting, calculation in advance

After receiving the data returned by the server, try to raise the result of CoreText typesetting, the height of individual controls, and the height of the cell as a whole

It is computed and stored in the properties of the model. When needed, it can be taken directly from the model, avoiding the process of calculation.

Use UILabel as little as possible and use CALayer instead. Avoid AutoLayout’s automatic layout technique and go for pure code

type

2. Pre-render, draw ahead of time

For example, circular ICONS can be processed in background threads in advance, stored directly in model data, when data is returned from the network.

Just go back to the main thread and call it

Avoid using CALayer’s Border, corner, Shadow, mask and other techniques, which trigger off-screen rendering.

3. Draw asynchronously

4. Global concurrent threads

5. Efficient asynchronous loading of images

8. How to optimize the power of APP?

The power consumption of the program is mainly in the following four aspects:

  • CPU

  • positioning

  • network

  • image

The optimization approach is mainly reflected in the following aspects:

  • Minimize CPU and GPU power consumption.

  • Use timers as little as possible.

  • Optimize I/O operations.

O Do not write small data frequently, but accumulate a certain amount of data before writing

O Read and write large amounts of data using Dispatch_io, which has been optimized internally in GCD.

O If a large amount of data is required, use a database

  • Network optimization

O Reduce compression of network data (XML -> JSON -> ProtoBuf) and recommend using ProtoBuf if possible.

O If the request returns the same data, NSCache can be used for caching

O Use breakpoint continuation to avoid re-downloading after network failure.

O Do not attempt to make a network request when the network is unavailable

O Long network requests that provide cancelable operations

O Batch transmission. When downloading a video stream, try to download it in chunks; ads can be downloaded at once

multiple

  • Optimization at the location level

O If you just need to quickly determine the user’s location, it’s best to use the requestLocation method of CLLocationManager.

After the locating is complete, the locating hardware is automatically powered off

O If it’s not a navigation app, try not to update your location in real time. Turn off location services when you’re done

O Minimize the positioning accuracy, such as try not to use the highest accuracy kCLLocationAccuracyBest

O need background location, Settings pausesLocationUpdatesAutomatically for as far as possible

YES, the system will automatically pause location updates if the user is unlikely to move

O do don’t make use startMonitoringSignificantLocationChanges, preferred startMonitoringForRegion:

  • Hardware detection optimization

O When the user moves, shakes or tilts the device, motion events are generated. These events are composed of accelerometers, gyroscopes,

Magnetometer and other hardware detection. These hardware should be turned off when testing is not required

Nine, how to effectively reduce the size of APP package?

There are two ways to reduce package size

Executable file

  • Compiler optimization

  • Strip Linked Product, Make Strings read-only, Symbols Hidden by Default set to YES

  • Disable exception support. Enable C++ Exceptions and Enable Objective-C Exceptions are set to NO and Other C Flags

add

-fno-exceptions

  • Detect unused Code with AppCode: menu bar -> Code -> Inspect Code

  • Write the LLVM plug-in to detect duplicate code, uncalled code

resources

Resources include pictures, audio, video, etc

  • The optimized way can compress the resources losslessly

  • Remove unused resources

What is off-screen rendering? Under what circumstances can it be triggered? How to deal with it?

Off-screen rendering is the operation of creating a new buffer in addition to the current screen buffer.

The off-screen rendering starts with the following scenes:

  • Rounded corners (triggered by maskToBounds)

  • Layer mask

  • shadow

  • rasterizer

Why avoid off-screen rendering?

The CPU GPU does a lot of work in drawing the render view. Off-screen rendering occurs on the GPU level and creates a new render buffer

Triggering OpenGL’s multi-channel rendering pipeline, switching graphics context will cause additional overhead and increase GPU workload. If the CPU

The GPU takes 16.67 milliseconds to complete, which will cause frame lag and drop.

Rounded corners and masks trigger off-screen rendering. Specifies the above property, marking it in the new graphics context, before healing,

Cannot be used for display when starting off an off-screen rendering.

  • In OpenGL, the GPU has 2 rendering methods

    • On-screen Rendering: Renders On the Screen buffer currently used for display

    • Off-screen Rendering: Creates a new buffer outside the current Screen buffer for Rendering

  • Off-screen rendering is a performance drain

    • A new buffer needs to be created

    • The entire process of off-screen rendering requires multiple context changes, first from the current Screen to the off-screen

(Off – Screen); When the off-screen rendering is complete, the rendering results of the off-screen buffer are displayed on the screen, and the context is required

The environment switches from off-screen to current screen

  • What actions trigger an off-screen rendering?

  • ShouldRasterize = YES

  • Mask the layer mask

  • Rounded corners with layer.masksToBounds = YES and layer.cornerRadius > 0

  • Consider using CoreGraphics to draw rounded corners, or ask an artist to provide rounded images

  • Shadow, layer.shadowXXX, if layer.shadowPath is set it will not render off-screen

11. How to detect off-screen rendering?

1. Emulator debug- Select color Offscreen – Renderd for off-screen rendering where the layer brightness turns yellow

2. Instrument- Select Core Animation- check Color Offscreen-Rendered Yellow

How off-screen rendering is triggered

Off-screen drawing is triggered when the following properties are set:

1, layer. ShouldRasterize

Rasterization concept: to transform a graph into an image composed of grids.

Rasterization: Each element corresponds to a pixel in the frame buffer.

2, Masks

3. shadows

4, Edge antialiasing (anti-aliasing)

Opacity 5, group opacity

6. Set rounded corners for complex shapes

7, the gradient

8 drawRect.

For example, we often deal with TableViewCell in our schedule, because TableViewCell redraws frequently (because of Cell reuse), if

The content of the Cell changes constantly, so the Cell needs to be redrawn continuously. If the Cell. Layer is set at this time, it can be rasterized. It causes a lot of off-screen rendering,

Reduces graphics performance.

If any render that is not in the current screen buffer of the GPU is called off-screen rendering, there is another special “off-screen render” side

Formula: CPU rendering. If we overwrite the drawRect method and draw using any Core Graphics techniques, yes

To CPU rendering. The whole rendering process is completed synchronously by CPU in App, and the rendered bitmap is finally handed over to GPU for display

.

We now have three choices: on-screen render, off-screen render, and CPU render. Which one should we use? It depends on the specific

Use scenarios to decide.

Try to render with the current screen

In general, we try to use the current screen rendering as much as possible, given the potential performance issues associated with off-screen rendering and CPU rendering.

Off-screen rendering VS CPU rendering

Since THE floating point calculation capability of GPU is stronger than that of CPU, the efficiency of CPU rendering may not be as good as off-screen rendering. But if only to achieve a simple effect

As a result, direct CPU rendering may be more efficient than off-screen rendering, which involves buffer creation and context switching

When operating

UIButton masksToBounds = YES set setImage, setBackgroundImage, [button]

setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@”btn_selected”]]];

Button setBackgroundColor:[UIColor redColor]]; There will be no off-screen rendering

For UIImageView, testing now (current version: iOS10) shows that rounding UIImageView does not trigger off within the performance range

Screen rendered, but setting a background color for UIImageView at the same time will definitely trigger. Triggering off-screen rendering has nothing to do with png.jpg

Everyday we use two properties of layer to implement rounded corners

imageView.layer.cornerRaidus = CGFloat(10);

imageView.layer.masksToBounds = YES;

The rendering mechanism of this process is that the GPU creates a new rendering buffer outside the current screen buffer to work on, i.e., off-screen rendering, which will

It gives us an extra performance penalty. If the number of such rounded corners reaches a certain level, frequent merging of buffers and contextual merging can be triggered

With frequent switching, the performance cost is reflected in the user experience in a macro way — dropping frames

How to detect layer blending?

1. Emulator debug- Select color blended Layers to indicate that the layers are blended

2, Instrument- select Core Animation- select Color Blended Layers

Avoid layer blending:

1. Ensure that the opaque property of the control is set to true to ensure that the backgroundColor is the same color as the parent view and is opaque

2. Do not set the alpha value below 1 unless otherwise required

3. Make sure UIImage has no alpha channel

UILabel layer blending solution:

IOS8 after setting the background color is not transparent color and set label. Layer. MasksToBounds = YES let label will only render her actual size of the area

Field, you can solve the layer mixing problem in UILabel before iOS8 you just set the background color to be opaque

Why did I set the background color and still get layer blending on iOS8?

UILabel before and after iOS8, before iOS8, UILabel used CALayer as the bottom layer, but starting with iOS8, UILabel

The bottom layer is changed to _UILabelLayer and the drawing text is also changed. There is a transparent edge around the background color, and this one is transparent

The edge of the Bounds is clearly beyond the layer’s rectangular area, and when you set the layer masksToBounds to YES, the layer will crop the image along the Bounds

Layer mixing problem solved

conclusion

Learning this matter, we should not be eager for quick success and instant benefits and eat fat at one time, but to keep learning, sustainable learning. Little drops of water wear away a stone. As a porter traveling from platform to platform, I also collected a lot of iOS development materials, interview materials. If that’s what you need, I have access to it. Click on the circles below if you need to. Finally, ask for a wave of likes and attention.

circle