One of the most valuable attributes in performance optimization is FPS:FramesPerSecond, which is actually the refresh rate of the screen. Apple’s iPhone recommends a refresh rate of 60Hz, which means that the GPU refreshes the screen 60 times per second, and each refresh is a frame. FPS is the number of frames refreshed per second. The FPS value of a static page is 0, which is of no reference value. The FPS value is only useful when the page is animated or sliding. The FPS value reflects the smoothness of the page, and stuttering is more obvious when the page is below 45.
Layer Blending:
Each layer is a texture, and all textures are somehow stacked on top of each other. For each pixel on the screen, the GPU needs to figure out how to mix these textures to get the RGB value of the pixel.
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 will do a lot of such compound operations. The more these operations are performed, the busier the GPU will be, and the performance will definitely be affected.
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 compositing, but will simply copy from this layer without thinking about anything below it (because it is obscured by it), saving 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 that the image is the same size as the UIImageView. Zooming in and out of images on the fly is expensive, especially if UIImageView is nested in a UIScrollView. If the image is loaded from a remote service and you don’t have any control over the size of the image, for example, before you download it, you can scale it once after the download, preferably with backgroundThread, 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 and more
view
It means more rendering, which means moreCPU
And memory consumption for that kind of nesting is a lotview
in
This is especially true for apps in UIScrollView.
- The technique we use here is imitation
UITableView
andUICollectionView
Do not create them all at oncesubview
.
Instead, create them as needed, and when they’re done, put them in a reusable queue. This way you only need to 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 the response from the remote server, images, and even computed results, such as the row height of a UITableView.
-
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, such as parsing data from JSON or XML. To avoid the bottleneck of using these objects, you need to reuse them, either by adding properties to your class or by creating static variables.
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. JSON deserialization is easy to use since iOS5 with official built-in JSON deserialization. But XML also has XML benefits. For example, parsing XML with SAX is like parsing local files; you don’t have to wait until the entire document has been downloaded to start parsing, as you do with JSON. When you deal with very large amounts of data, you can dramatically reduce memory consumption and increase 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 take 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 unnecessary javascript whenever possible and avoid using overly large frameworks. It would be nice to just use native JS. Load javascript that does not affect page presentation, such as user behavior statistics scripts, asynchronously whenever possible. 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 pre-calculated path. The problem is that calculating the path yourself can be difficult in some views, and you need to update the shadow path every time the View’s frame 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 data, such as simple Booleans, and beyond that you need to consider other options
-
What about structured files like XML? In general, you need to read the entire file into memory to parse, which is very uneconomical. Using SAX is another hassle.
-
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 load only the objects you need with specific queries.
-
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’S C API.
Senior three,
First of all, as a developer, there is a learning atmosphere with a communication circle is particularly important, this is a my ioser public number: programming Xin, whether you are small white or big ox welcome to enter, let us progress together, common development!
1. Accelerate startup time. It’s important to open your app quickly, especially when you’re opening it for the first time. First impressions are so important to your app. What you can do is make it do as many asynchronous tasks as possible, such as loading remote or database data and parsing data. Avoid xiBs that are too large because they are loaded on the main thread. Try to use Storyboards that don’t have this problem! Be sure to disconnect the device from Xcode to test startup speed
2. Use Autorelease Pool. NSAutoreleasePool is responsible for releasing the Autoreleased objects in the block. Normally 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 will continue to decrease until the objects are released. This is because memory is only freed when UIKit runs out of autoRelease pools. 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 an image from a bundle, one is imageNamed, the other is 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 use Unix timestamps. You can easily convert from timestamp to NSDate:
This will be faster than parsing a date string in C! Note that many Web apis return timestamps in microseconds, because this format is easier to use in javascript. Remember to divide by 1000 before dateFromUnixTimestamp.
How do you optimize your code for performance?
-
Use performance analysis tools, including the static Analyze tool, and the runtime Profile tool, which can be started from Product->Profile in the Xcode toolbar. For example, the test program starts the runtime when clicking the Time Profiler application starts running. You can get the distribution and percentage of time spent running the entire application. In order to ensure that data analysis is true in a unified use scenario, it is necessary to use a real computer, because the simulator runs on a Mac, and the CPU on a Mac is usually faster than that on an iOS device.
-
To prevent an app from taking up too much of the system’s resources, Apple engineers working on iOS devised a “watchdog” mechanism. The watchdog monitors application performance in different scenarios. If the running time specified for the scenario is exceeded, the watchdog forces the application to terminate. 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 to 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, and do not request a delegate
UIImage loading image performance problem
-
ImagedNamed initialization
-
ImageWithContentsOfFile initialization
* imageNamed by default caches images in memory after a successful loading. This method looks up an image object in the system cache with a given name and returns it. If no corresponding image object is found in the cache, the image is loaded from the specified location, the object is cached, and the image object is returned.
-
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 using scenarios for programming, it should be differentiated according to actual application scenarios. Although UIimage is small, problems will be highlighted when using more elements.
-
Do not do time-consuming operations in viewWillAppear: viewWillAppear: call viewWillAppear before the view is displayed. For efficiency reasons, do not handle complex and time-consuming operations in the method. This method sets simple things like the view’s display properties, such as 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 renders these views in an optimal way. This simple property can be set either in IB or in code.
-
Avoid xiBs that are too large: Make it as simple as possible to configure a separate XIB for each Controller. If possible, separate the view hierarchy of a ViewController into a separate XIB. When you load a NIB that references an image or sound resource, the NIB load code writes the image and sound file to 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, responding to input, and so on, it’s all done on it, and most of the things that block the main process are your app doing I/O operations that involve reading or writing to external resources, like storage or networking.
- in
Image Views
To resize the picture
If you want to display an image from a bundle in a UIImageView, you should make sure that the image is the same size as the UIImageView. Zooming in and out of images on the fly is expensive.
Tell me your use Instrument
Experience optimizing animation performance (don’t ask me what isInstrument
)
Facebook startup time optimization
1. Slim request dependencies
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, so as to be displayed on the display device. The essence of rasterization is coordinate transformation and geometric discretization. When we use UITableView and UICollectionView, we often encounter the same style of each Cell. At this point we can use this property to 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 is better
Six, how to draw a high performance rounded corner?
The size of views and rounded corners has no effect on frame rate, quantity is the core output of damage
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, picture 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 the texture size exceeds this size, IT will occupy CPU resources for processing, so the texture size 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 calculate the results of CoreText typesetting, the height of individual controls and the height of the whole cell in advance and store them in the attributes 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 technology and adopt a pure code approach
2. Pre-render, draw ahead of time
For example, circular ICONS can be processed in the background thread in advance and stored directly in the model data when the network returned data is received. After returning to the main thread, they can be called directly to avoid using CALayer’s Border, corner, shadow, mask and other technologies, which will 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,
The network,
The image,
The optimization approach is mainly reflected in the following aspects:
· Reduce CPU and GPU power consumption as much as possible.
· 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 multiple times
- 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 position, try to set up pausesLocationUpdatesAutomatically to YES, if the user is unlikely to move the system will automatically suspend position update
O try not to use startMonitoringSignificantLocationChanges, priority startMonitoringForRegion:
- Hardware detection optimization
O When the user moves, shakes or tilts the device, motion events are generated, which are detected by hardware such as accelerometers, gyroscopes and magnetometers. 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, Enable Objective-C Exceptions set to NO, 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, which will create a new rendering buffer and trigger OpenGL’s multi-channel rendering pipeline. Switching graphics context will cause extra overhead and increase GPU workload. If the CPU GPU takes 16.67 milliseconds to complete, it will stall and drop frames.
Rounded corners and masks trigger off-screen rendering. Specifies the above property to indicate that it cannot be used for display in the new graphics context before it has healed.
-
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
-
In the whole process of off-screen rendering, the context needs to be changed several times, first from the current Screen (on-screen) to off-screen (off-screen); When the off-screen rendering is finished, the rendering results of the off-screen buffer are displayed on the screen, and the context needs to be switched from off-screen to the 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 the Redrawing of TableViewCell is very frequent (because of Cell reuse), if the content of the Cell changes constantly, then the Cell needs to be redrawn constantly, if Cell. Layer can be rasterized at this time. It will cause a lot of off-screen rendering and reduce the graphics performance.
If any rendering that is not in the current screen buffer of the GPU is called off-screen rendering, then there is another special “off-screen rendering” : CPU rendering. If we override the drawRect method and draw using any Core Graphics technology, we’re dealing with 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? This depends on the specific usage scenario.
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 for a simple effect, direct CPU rendering may be more efficient than off-screen rendering, which involves time-consuming operations such as buffer creation and context switching
The UIButton masksToBounds = YES and set setImage, setBackgroundImage, [buttonsetBackgroundColor: [UIColor colorWithPatternImage:[UIImage imageNamed:@”btn_selected”]]];
Button setBackgroundColor:[UIColor redColor]]; There will be no off-screen rendering
As for UIImageView, testing now (current version: iOS10) shows that rounding a UIImageView does not trigger an off-screen rendering, as far as performance is concerned, but setting a background color for UIImageView does. 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, that is, off-screen rendering, which will bring us additional performance loss. If enough of these rounded corners trigger frequent merging of buffers and frequent context switching, the cost of performance can be seen in the user experience as 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, can solve a UILabel layer mixed problem
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, the bottom layer of UILabel has changed to _UILabelLayer, and the drawing text has changed. There is an extra transparent edge around the background color that clearly extends beyond the layer’s rectangular area. Setting the layer masksToBounds to YES will crop the layer along the Bounds.