preface

First, why do we need to do performance optimization?

Performance: It is an excellent ability. Wake up fast, run long, stable. This is the ability to make your users feel good about your game, which is characterized by fast loading, no heat, smooth running, and no lag. So, the ultimate goal of performance optimization is to make your users feel good, but not at the expense of yourself, considering the cost and side effects (don’t use Viagra too often, right?). To optimize performance, first of all, what are the factors that affect performance? Is the physical strength is not enough to strengthen exercise, is overworked should learn to rest. What factors affect performance in our game?

What are the factors affecting performance?

If you don’t know how to analyze it, let me give you a guide. When you play a game, first load your game into memory. Foreplay is too long, and you’re going to get tired of waiting. So the first question comes, how to optimize the game loading speed (3, 1), let’s first record, the following one by one.

Second, you’ve managed to put something in memory, but the screen is empty, and it’s not making any noise. It’s not a good experience! That is to say, screen rendering of the game interface takes too long, which is stuck and needs to be optimized. Therefore, the second question, how to optimize the rendering speed (3, 2)?

At the end of the game, how is the speed affected? Related to device memory, CPU, code, so we need to do memory optimization (3, 3), CPU usage and performance optimization (3, 4).

Third, from what aspects of performance optimization?

1. How to optimize the game loading speed 【 load optimization 】 Ask you a question, you have a 8M things and others have a 1M things, you say who will load into the first? It must be 1M, so the first thing to do is to optimize the package size.

** What are the methods for optimizing package size? ** First think about what’s in your bag. What things take up the most memory, and what things are most likely to compress? Under the project path are res, Scenes, Scripts, game engines, etc. In short, the package consists of resources and code.

** (1) Resources: pictures, sounds, animations, etc. ** Avoid large images: solid color images or regular images are represented as one-pixel images, and button backgrounds with rounded corners are displayed as nine-grid images. In addition, it should be noted that the maximum image size supported by CoCOS Creator is 20482048. If the image size exceeds this size, there will be some problems in the display. It is common that some Spine animations fail to pay attention to the resource image size after packaging, resulting in abnormal animation display. If the map resource is larger than 20482048, as is common in some Mmos, the map resource needs to be shred into images smaller than 2048×2048 and then pieced together in the game.

** Image compression: ** image compression format: background, JPG volume is smaller than PNG, background image JPG, many image formats, export art, these images, still can be compressed. Baidu search online compression picture, you can find the corresponding website direct operation. https://www.yasuotu.com/

Image resolution: 1920×1080 > 960×540, reduce resolution; –> Reduced clarity; Whenever possible, use nine grid images instead of a full image button 200×100, 300×100; –> Greatly reduce the image split rate, so that you can save resources;

Modularization of image resources:

Similarly, it is also a better way to classify and package the art resources and frames of each interface into an atlas, and modularize the resources. This has the following benefits at load time and when the game is running:

1. Improve the loading speed

Save time for opening/closing files multiple times

2. Reduce file size

When multiple images are merged together, there will be some optimization on the package body

3. Reduce DrawCall

When used, because these art resources are used together, putting them in a single image set can reduce the number of drawcalls for rendering and optimize the performance of rendering.

When these resources are not needed, for example, when a page does not need to be displayed, you can release all the resources on the page to avoid occupying memory. In addition, common resources can be uniformly packaged in a map set, so that these common resources and memory, easy to use. Avoid frequent repeated releases and loads. Similarly, sound can be handled in the same way. Music sound resources (compressed format background music size, number of music, channel, sampling rate). www.aconvert.com/cn/audio/

The following is a comparison of the compressed and pre-compressed music file size, reduced to one tenth of the pre-compressed music file size.

Character:

If possible, do not bring your own library. (1) Special effects text, try to use bitmap font, a few letters + pictures, the volume is far less than a complete font library, performance is better, numbers, interface text, such as our “Speed Racer” is to use this scheme! PNG +. FNT file; (2) Use the system font as much as possible; (3) Font library can compress fontmin; A specified number of fixed words; (4) Bitmap word or vector word, which performance is better? ? ? Bitmap words: fast speed, but large memory; Vector word: slow speed, but small memory;

Read data from a file → deserialize data → restore the PreFab node tree → Preprocess → Instantiate The prefab section is optimized for loading in two places: One is load time optimization, and the other is instantiation time optimization. Larger Prefab files tend to take longer to load, and they tend not to be equal-to-square, but rather square. For example, reading a 100KB file might take 10 milliseconds, but for a 1M or 2M file, we might load it in hundreds of milliseconds instead of 100 milliseconds. With a prefab file like this, we have to think about, do all the nodes in it have to be a Prefab? Is it possible to split into more than two prefab pieces and assemble them by splicing? We can think of a Prefab as a functional module, and functional modules are not as big as possible, but as simple as possible. Following this principle, we can make a better split of PreFab. Remember: single responsibility principle, clear logic, decoupling, easy to maintain later. Load fast!!

② Lazy loading of resources

You can find it in the scene. Click on the edited Prefab resource in Creator’s Explorer, and in the property inspector you can see the option to lazy-load the resource. Check this option to reduce the load time of PreFab, but the first display time will increase.

This is because when checked, resources referenced by Prefab, such as images and sound effects, are not loaded at load, but are loaded when Prefab is first displayed. Therefore, you need to choose according to the specific use environment.

③ Choose the optimization strategy

In preFab’s property inspector, you can see the optimization policy option. This also requires us to choose according to the actual use situation. When we select the “optimize multiple creation performance” option, Prefab loads and performs a preprocessing operation, which dynamically generates some Prefab instantiation code and passes it to the JIT for optimization. This will greatly reduce the elapsed time during instantiation and, accordingly, increase the elapsed time during load.

When we select the “optimize single-create performance” option, prefab skips the preprocessing step after loading, which reduces load time significantly, but increases instantiation time. For example, for some fixed UI interfaces, prefab is usually made to facilitate loading scenes or function division. The Prefab will only be loaded once, so you can select this option to improve the loading performance.

One thing to note: the optimization strategy option is not available on the wechat mini game platform because dynamic loading code is disabled and eval cannot be used.

** (2) Code: ** Code volume (engine + business logic code) – big head in engine. Solution: engine: very simple, as long as you do not want to remove the module can, you want to know which module is the bulk of the physical engine, can not use the module, not. [Project Settings] – [module Settings], only pack necessary modules.

Not if you can use TileMap, because Cocos has a good enough 2D editor to replace TileMap and use a collision detection engine instead of a physics engine. Through the project setting, the function modules that are not used in the game can be removed to reduce the package size. As shown below, remove unnecessary modules and pack them again.

The business logic code in general we can’t change, your business logic is pretty much the same, but be aware of a fact that 95% of you will miss: the Settings file in the SRC folder.

You can actually change the Settings file size. The first thing you need to understand is who decides how big it is, right? If you don’t understand this, you won’t be able to optimize, even if someone tells you to. All resources that need to be loaded into the code should be placed in Resources or never in the Resources folder. Because the application does not know which resources need to be loaded or when you will load them, it will create resource mappings in the Settings file.

As shown below, the size of the Settings file is compared between placing the resource in res and in the Resources folder. Note: You need to clear build before packing.

2. How to optimize the rendering speed

Rendering optimization mainly focuses on how to reduce draw call. The more draw call there is, the greater the pressure of rendering will be, and the corresponding frame rate may decrease. Under normal circumstances, if draw call exceeds 100, there may be a lag, so pay attention to this aspect of optimization. Draw call: the object in the game scene is submitted to the graphics card for drawing in several times, which is equal to the drawall times. 100 objects, 100 times delivered to the GPU is 100 draw calls.

Why does excessive draw call affect performance? **GPU: Each time you draw our graphics — “can swallow a certain number of triangles at a time, if your draw call is too high, the GPU could eat more triangles at a time, but you don’t feed me, the GPU performance is not working. CPU: 10 sprites, — “10 pictures; Each render pipe can only be drawn with a single texture, each Sprite texture object is not the same, so it is impossible to draw in a draw call exactly what can be drawn? Mesh is the same — texture is the same, shader is the same, parameters are the same, draw call is the same — > draw; For example, 10 objects: sprite1, sprite2, sprite3, label, 9 grid Sprite, Sprite; Recommended methods:

[1] Merge rendering batches to reduce DrawCall and improve rendering performance

(1) Use automatic atlas or TexturePacker to package the broken images: only sprites in the atlas can be drawn in a draw call → batch together. By doing so, multiple Sprites can render textures from the same atlas image, and merging render batches from these sprites can reduce the DrawCall and CPU overhead. (2) When combined batch, try not to disrupt the combined batch: for example, the emergence of the label above disrupts the structure of Sprite, so the combined batch cannot be done. (3) Why does label make a separate draw call? The text is drawn in the texture. (4) Resource processing to reduce the number of Mask components: Since the Mask component needs to add render command to modify GL state before and after stencil and content, using Mask will interrupt our DrawCall batch processing. For some special displays, such as rounded ICONS, if conditions permit, try not to use Mask components for processing, but through processing resources to achieve the same effect. Currently, Mask, Spine, and DragonBone components all interrupt batch processing, so we need to avoid such interruptions in the node structure. (5) Reuse nodes to reduce the number of nodes: when displaying or hiding this interface, a large number of nodes will bring a large amount of enable and Disable overhead. For example, the ranking of friends, suppose there are 1000 friends, there is no need to set 1000 nodes, just set the nodes displayed on one page, and then change the display content of these nodes.

The fastest way is to merge the fragments into an atlas, and then place nodes in the same atlas in order, without inserting nodes in other atlas.

3. Memory optimization

Memory management of static resources: Static resources refer to all resources referenced directly or indirectly in a scenario (resources dynamically loaded by scripts are not included). In the scenario resource attribute editor, select Automatically Release resources. In this way, static resources used in the original scenario are automatically released when switching scenarios, saving memory usage.

Memory management for dynamic resources:

Cc. Loader is used to load and manage dynamic resources. Note that all the methods in CocosCreator that load resources through cc.loader are asynchronous. Therefore, you need to confirm that the load is complete in the callback before using the resource. You can also use the CC.loader. GetRes API to obtain resources synchronously, but you need to check the resources you get. If the resources are not loaded or not loaded, you need to wait or load them through cc.loader. This way the whole code will be clearer and avoid falling into JS callback hell. For example:

1. `_loadRes = function(url, type, callback){` 2. `cc.loader.loadRes(url, type, function(){` 3. `if(! err){` 4. `callback(prefab); '5.'} '6.'}); ` 7. `}` 8. `Cc.loader.getRes` 9. `_createPrefab(url){` 10. `var prefab = cc.loader.getRes(url, cc.Prefab); ` 11. `If(prefab ! == null&& typeof(prefab) ! == "undefined"){` 12. `return cc.instantiate(prefab); ` 13. `}` 14. `returnnull; ` ` 15. `}Copy the code

By simply encapsulating the two methods, you can keep your code clean and readable when you use it. Another point to note is that cc.loader also provides the onProgress callback when batch loading is performed, and one of the three parameters in this callback is called.

TotalCount does not refer to the total number of resources loaded, but to the number of dependencies that need to be loaded to load the resource. For example, when loading a SpriteFrame, its totalCount is 3. The three items are json, texture2D, and SpriteFrame. So when totalCount is 0, it doesn’t mean that the total number of loaded resources is 0, it means that those resources are already loaded in memory and ready to use.

Finally, there is an idea of memory usage: reuse everything that can be reused. Reuse, not only to save on the overhead of alloc, but also to avoid the overhead of GC.

Things like lost health numbers in combat, enemy health tanks, monsters, bullets, hero avatars, etc., are all things we often go back to for reuse. For some common complex objects, we can use the object pool NodePool for reuse. For basic objects, we can directly assign values to achieve reuse purposes.

4.CPU and performance optimization

1. Absolutely avoid endless loops. 2. Control the game frame rate. 3, H5 games, JS code level optimization


1.  `for(var i=0,len=arr.length; i<len; i++){`

3.  `}`

Copy the code

4.JS exception capture

1. 'Try_catch' 2. 'Once an exception is thrown, efficiency plummets. Try to avoid trying in the for loop. `Copy the code

5. Be careful with global variables! 6. Optimize the node tree and reduce the number of nodes. 7. Do not mount too many Prefab in the scene, but make some Prefab dynamically loaded. ** 4. What should performance optimization pay attention to? ** Efficiency, cost. Don’t spend 90 percent of your time and cost trying to get a 1 percent performance improvement. Most of the time, you have to choose the lesser of two evils.