Location>code7788 >text

vivo game center package volume optimization solution and practice

Popularity:987 ℃/2024-11-18 09:06:27

Author: Ke Jie from vivo internet front-end team

Introduces the necessity of App package size optimization, the effective measures in the actual optimization process of Game Center App, including some optimization suggestions and optimization ideas.

I. The need for packet volume optimization

The relationship between installer size and download conversion rates is roughly inversely proportional, i.e., the larger the installer, the worse the download conversion rate. google had given a statistic at Google Conference 2019 that for every 6MB rise in package volume size, the app download conversion rate drops by 1%, and the performance may vary in different regions.

APK reduced by 10MB, conversion rate increased in different countries

(Note: Data fromgoogleplaydev:Shrinking APKs, growing installs

Game Center APK Composition

The APK contains the following directories:

  • META-INF/: contains, signature file, manifest file.

  • assets/: Contains the application's resources.

  • res/: contains resources that are not compiled in.

  • lib/: supports so files for the corresponding CPU architecture.

  • : Resource index file.

  • : A dex file is understood to be a collection of project code compiled into a class file.

  • : Contains the core Android manifest file. This file lists the application name, version, access rights, and referenced library files.

It was found that libs, res, assets, resources are the major parts of the package that take up a lot of volume, and the optimization mainly starts from these aspects.

Third, the package volume detection tool

Matrix-ApkChecker, as part of the Matrix system, is a tool for analyzing and checking Android installation packages. It detects whether there is a specific problem with an APK according to a set of rules, and outputs a more detailed report on the results, which can be used for analyzing and troubleshooting the problem as well as version tracking.

Configure the Game Center Json to detect whether the APK has been obfuscated, PNG files without alpha channel, uncompressed file types, redundant files, useless resources, and other information.

The analysis of the generated inspection files can optimize quite a lot of volume.

Introduction to the tool Matrix Apkcheck:/Tencent/matrix/wiki/Matrix-Android-ApkChecker

IV. Package volume optimization measures

4.1 Large PNG without Alpha Channel

There are more of these types of diagrams in the project, they can be replaced with JPG or WebP diagrams, which can reduce the size quite a lot.

4.2 Code Reduction

With the business iteration, many business scenarios will not be used anymore, related resources and class files can be deleted, and the res and dex in the corresponding APK will be reduced accordingly. Game Center removes some business scenarios and resources that are not used after iteration.

4.3 Minimal configuration of resource files

For internal sales projects, the local or SDK files for multiple languages are not used at all. This part of the resources can be optimized to reduce the size.

Add resConfigs "zh-rCN", "zh-rTW", "zh-rHK" under APP. This configuration does not affect the display of English, Chinese, Traditional Chinese, Traditional *, and Traditional * languages.

Resource File Minimization Before Configuration

After the resource file is minimally configured

4.4 Optimization of allocation of resources

Many projects in order to adapt to various sizes of resolution, the same resource may be placed in a different resolution of the directory of various files, and now the mainstream models are xxh resolution, the game game center for the built-in APK, configured to prioritize the use of "xxhdpi", "night-xxhdpi".

If there is a resource file for xxhdpi or night-xxhdpi, it will prioritize the file in the resolution directory, and if not, it will fetch the sub-resources in the original resolution directory, which can avoid the situation that the resource cannot be found.

defaultConfig {
        resConfigs isNotBaselineApk ? "" : ["xxhdpi", "night-xxhdpi"]
}

 

 

4.5 Built-in Package Removal v1 Signature

Also for the built-in packages, which are definitely all Android 7 and above, consider removing the v1 signature.

signingConfigs {
    gameConfig {
        if (isNotBaselineApk) {
            print("v1SigningEnabled true")
            v1SigningEnabled true
        } else {
            print("v1SigningEnabled false")
            v1SigningEnabled false
        }
        v2SigningEnabled true
    }
}

 

After removing the v1 signature, the three files shown above will disappear from the APK, and the size of the APK will be reduced by about 600k.

4.6 Action Resource File Optimization

It was found that the project used a lot of GIFs, Lottie files, SVG files, which took up a large portion of the volume. Considering to replace this part with smaller animation files, the game center is now connected to the PAG program. Replaced some GIFs and Lottie files.

PAG files use an extensible binary file format that allows for the integration of image and audio resources in a single file, exporting the same AE animation content, and is significantly ahead of similar solutions in terms of file decoding speed and compression rate, approximately 0.5 times that of Lottie, and 0.2 times that of SVG.

In fact, due to the design of the exported Lottie or GIF is not standardized, in the export of the PAG file will remind the optimization point, the actual part of the resources of the compression ratio of 80 ~ 90%, some of the animation resources from hundreds of K down to tens of K.

You can refer to the PAG website for details:/Tencent/libpag/blob/main/README.zh_CN.md

The larger GIFs and more Lottie images have been replaced with PAGs on the Game Center side.

 

give an example

(1) For the header image on the ranking page of the game center, the size of the GIF exported by UI is 701K, and the size of the image with the same effect after replacing it with the PAG format is 67K, which is less than 1/10 of the original size.

(2) Optimization of the Lottie animation in the entrance space of the Game Center.

A Lottie effect looks like this, a bunch of resource issues plus a Json file. An animation like the one above has 112K resources, and after converting the same animation to PAG format, the resource size becomes 6K, which is only about 5% of the original size. After that, we will prioritize the use of PAG for new animations.

4.7 Optimizing images during compilation

In the case of the Game Center App, for example, image resources take up about 25% of the package size, so image compression is a way to get immediate results.

The WebP format has a higher compression rate than traditional PNG, JPG, etc. and supports both lossy, lossless, and transparency.

The idea is to insert a WebP compression task between the mergeRes and processRes tasks, using Cwebp to compress the image during compilation.

(Note: Image courtesy of/zh/guide/shrinking/#pngquant-provider

Solutions in place

(1) You can use the droplet scheme booster, booster-task-compression-cwebp .

Reference Links:/didi/booster

(2) the company's internal official website module is also similar to the booster-based plug-ins, based on the booster provided by the API implementation of the image compression plug-ins. After the compression of all the pages need to carry out a spot check to prevent image distortion, for distorted images, you can use the mechanism of whitelisting.

4.8 Loading so dynamically

Also take the game center as an example, the percentage of so reaches 45.1%, which can be dynamically loaded for the so with fewer and larger usage scenarios, downloaded to the local area and dynamically loaded in the scenarios that need to be used.

The process of using the scenario to go to the server side to download to load locally can be represented by the following flowchart.

The process can be summarized as download, unzip, load, and the main problem is solving the so loading problem.

The traditional approach to loading so libraries is to use:

(library);

UnsatisfiedLinkError often occurs, the Relinker library can significantly reduce the probability of reporting errors:

(context, "mylibrary")

Specific references can be made:/KeepSafe/ReLinker

In the case of on-demand loading, risk and benefit go hand in hand, and there are a lot of situations that need to be taken into account, such as download trigger scenarios, network environments, whether there is a degradation strategy for loading failures, and so on, and there is a need to do a good job of prompting interactions to the user.

4.9 Built-in packages are only 64-bit so

The CPU architecture of newly released cell phones is arm64-v8a, which corresponds to the ARMV8 architecture, so only 64-bit so is packaged for the built-in project.

ndk {
            if ("64" == localMultilib)
                abiFilters "arm64-v8a"
            else if ("32" == localMultilib)
                abiFilters "armeabi"
            else
                abiFilters "armeabi", "arm64-v8a"
        }
//included among theselocalMultilibVariable for Configuration Item
 
String localMultilib = getLocalMultilib()
String getLocalMultilib() {
    def propertyKey = "LOCAL_MULTILIB"
    def propertyValue = (propertyKey) ? (propertyKey) : "both"
    println " --> ${}: $propertyKey[$propertyValue], $propertyKey[${}]"
    return propertyValue
}

4.10 Enabling Code Obfuscation, Removing Useless Resources, and ProGuard Obfuscating Code

android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
        }
    }
}

Both shrinkResources and minifyEnabled must be enabled.

Special note: One thing to emphasize here is that useless resources or images are not really removed after turning it on, but a placeholder symbol of the same name is used.

This can be done with ProGuard, which detects and removes unused classes, fields, methods, and properties from code, in addition to optimizing bytecode, removing unused code directives, and obfuscating classes, fields, and methods with short names.

is the default obfuscation profile provided by Android, in the Android sdk /tools/proguard directory of the configuration, is our custom obfuscation profile, we can put our custom obfuscation rules in it.

android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile(''),''
        }
    }
}

4.11 R File Inline Optimization

If our App architecture is as follows:

The R files generated for each module when compiled and packaged are as follows:

R_lib1 = R_lib1;
R_lib2 = R_lib2.
R_lib3 = R_lib3.
R_biz1 = R_lib1 + R_lib2 + R_lib3 + R_biz1(R for biz1 itself)
R_biz2 = R_lib2 + R_lib3 + R_biz2(R for biz2 itself)
R_app = R_lib1 + R_lib2 + R_lib3 + R_biz1 + R_biz2 + R_app(app's own R)

It can be seen that the R files of each module will contain the R files of the lower level components, and the ids generated by the lower level modules will not only generate an R file by themselves, but also generate an R file globally, so the number of R files will also be inflated. In the case of multiple modules, the R files in the APK will expand dramatically, which will have a great impact on the package size.

Since the resource IDs in the current R file of the App module are all final, the Java compiler will inline the final constants during compilation, replacing the variables with constant values, so that there is no reference to the R file of the App module in the project, and the R file of the App module will be removed during the code reduction phase, thus achieving the optimization of the package size. The goal is to optimize the package size by removing the App module R file during the code reduction phase.

Based on the above principle, if we convert the resource IDs in the library module to constants, then the R file of the library module can also be removed, which can effectively reduce the size of our package.

There are a number of open-source methods for inlining R files, such as booster, which is open-sourced from DDT, and bytex, which is open-sourced from Bytex, both of which include plug-ins for inlining R files.

booster reference:

/zh/guide/shrinking/#%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8

bytex Reference:

/bytedance/ByteX/blob/master/access-inline-plugin/

V. Optimization effects

5.1 Optimization effects

All of the above optimization measures are adopted in the actual Game Center, taking one of the same versions of Game Center as an example, the before and after volume comparison is shown in the figure below:

(1) The percentage of packet size optimization reaches 31%, and the packet size is reduced by about 20M, which can improve the conversion rate of the application by about 3% in the long run.

(2) Startup speed improved by 2.2% points compared to the unoptimized version.

5.2 Summary

(1) Before readers want to optimize the volume, they need to analyze the ratio of each module of the APK, and optimize the parts with high ratio, for example: lib, res, assets, resources in the game center accounted for a high percentage of the optimization is targeted;

(2) Measures such as switching of animation schemes, dynamic loading of SO, and optimization of images during compilation are long-lasting, and the longer the time, the more significant the possible reduction in size compared to no optimization;

(3) Minimal resource file configuration, configuration resource optimization, simple and effective;

(4) The dex will be further explored in the future. At present, the code in the project is basically doing addition and getting more and more complex, with very little subtraction, resulting in a gradual increase of the dex, and we are still exploring how to further reduce the size of the dex.