We use essential cookies for the website to function, as well as analytics cookies for analyzing and creating statistics of the website performance. To agree to the use of analytics cookies, click "Accept All". You can manage your preferences at any time by clicking "Cookie Settings" on the footer. More Information.

Only Essential Cookies
Accept All
Best PracticesPerformance Performance Optimization CasesOptimizing Resource and StorageOptimizing Image Loading

Optimizing Image Loading

Overview

Since the CPU needs to decompress the images into the texture format for the GPU to directly read them, the CPU processing time increases and image loading is delayed when the number or size of images exceeds a specific threshold. In addition, the images generated after decompression occupy a large amount of memory, which increases the memory pressure and may cause frame freezing and frame loss. This topic describes solutions for optimizing preset and non-preset images. Preset images are mainly optimized by using a texture compression technology. Non-preset image loading optimization policies are as follows: compressing images by using an image editing tool, reducing GIF image resolution, optimizing network images, preferentially using WebP images, and performing down-sampling on images by using autoResize.

Optimizing Preset Image Loading

Preset images are local images packed in the app package and stored in the resource/base/media directory. You can optimize the loading of preset images using texture compression.

Texture Compression

Texture compression is used to reduce the size of texture image files. You can use texture compression to transcode and compress preset images during the build process, thereby reducing the CPU processing time, lowering memory usage, and improving app performance.

How to Implement

Without texture compression, preset images must be decoded by the CPU into a pixel map before being uploaded to the GPU for texture generation. This process is time-consuming. You can use texture compression technology to complete CPU decoding and texture generation in advance in the compilation and build phases, reducing the time for the CPU to process images. For texture compression, relevant properties must be configured in the compilation file. During the build process, preset images are located and converted into texture streams based on these configurations. Super-compression encoding is then applied to generate super-compression streams. After compilation, during runtime, super-compressed data is decoded to generate texture streams. The GPU then reads these streams for rendering and display.

Texture compression compresses preset images in the compilation and build processes. You need to configure texture compression parameters in the compilation file of the editor. Based on the parameters, Hvigor reads the files to be compressed, constructs the restool command to parse resources, and then generates a resource file list. Then, Hvigor traverses the file list and transcodes the files to be converted to the texture format. Converted resource files are no longer packaged into build products. The texture files and unconverted files are then built to generate resource products.

The following figure shows the timing for enabling texture compression for compiling and building resource files.

NOTE

Texture compression processes preset images in advance during compilation and build processes, which may increase the compilation time and package size. If images occupy a large amount of space and have a significant impact on the package size, you are advised to filter images to reduce the texture compression overhead.

Scenario Case

Images cannot be directly rendered by the GPU. The CPU needs to decode the images and upload them to the GPU, which takes time. When a certain number of preset images are rendered on a page at the same time, the image completion delay may increase. The following figure shows how to switch between tabs. When you swipe right to switch to tab2, the new page loads 40 PNG images and 40 JPG images using the horizontal layout. The image completion delay is significantly different when texture compression is enabled and disabled. The following figure shows the switching process when texture compression is disabled.

If texture compression is not used, when you swipe right to switch to tab2, the loading of some images may be delayed because multiple preset images need to be loaded on the new page. As a result, white blocks occur.

Project Configuration

Before using texture compression, you need to perform basic configurations and select the preset image to be super-compressed. You can add the media and filters properties to the compression object in the build-profile.json5 configuration file at the project or module level.

media: contains the enable property that specifies whether to enable texture compression. The default value is false, indicating that texture compression is disabled. To enable texture compression, set enable to true.

filters: contains the method, files, and exclude property objects.

  • method contains the type and blocks properties. type can be set to sut or astc. blocks is used to set the extended parameters of the conversion type. Currently, only 4x4 is supported.
  • The path, size, and resolution properties in files specify filtering by path, size, and resolution, respectively.
  • exclude has the same properties as files, which are used to delete files that do not need to be compressed from files.

For details, see compression. The sample code for configuring texture compression is as follows:

Collapse
Word wrap
Dark theme
Copy code
  1. "buildOption": {
  2. "resOptions": {
  3. "compression": {
  4. "media": {
  5. "enable": true // Whether to enable texture compression for media images
  6. },
  7. // Filtering of texture compression files. This field is not mandatory. If this field is not set, all images in the resource directory will be compressed
  8. "filters": [
  9. {
  10. "method": {
  11. "type": "sut", // conversion type
  12. "blocks": "4x4" // The extended parameters of the conversion type
  13. },
  14. // Specifies the files used for compression. Only files that meet all conditions and are not excluded can be compressed
  15. "files": {
  16. "path": ["./**/*"], // All files in the specified resource directory
  17. "size": [[0, '1000k']], // Files with a specified size of less than 1000k
  18. // Pictures with a resolution smaller than 3000 x 3000
  19. "resolution": [
  20. [
  21. { "width": 0, "height": 0 }, // minimum width and height
  22. { "width": 3000, "height": 3000 } // Maximum width and height
  23. ]
  24. ]
  25. },
  26. // Remove files that do not need to be compressed from the files list. Only files that meet all filtering conditions are deleted
  27. "exclude": {
  28. "path": ["./**/*.webp"], // Filter all webp files
  29. "size": [[0, '1k']], // Filter files smaller than 1k in size
  30. // Filter images with a resolution smaller than 1024 x 1024
  31. "resolution": [
  32. [
  33. { "width": 0, "height": 0 }, // minimum width and height
  34. { "width": 1024, "height": 1024 } // Maximum width and height
  35. ]
  36. ]
  37. }
  38. }
  39. ]
  40. }
  41. }},

NOTE

  1. filters: When both project-level and module-level filtering conditions are configured, module-level filtering conditions are preferentially used for matching. If module-level filtering conditions are matched, project-level filtering conditions are ignored. If module-level filtering conditions are not matched, project-level filtering conditions are applied.
  2. type:
    • astc: adaptive scalable texture compression. It is a GPU-friendly texture format that allows for faster display on devices with less memory usage.
    • sut: super compression for texture. It is a GPU-friendly texture format that allows for faster display on devices with less memory usage. Compared with astc, it offers a higher compression ratio and less ROM usage.
  3. size and resolution: The value of size is a one-dimensional array, and the value of resolution is a two-dimensional array.

Therefore, the value range of [0-1k, 1k-2k] is the same as that of [0-2k] for size matching.

When matching is performed by resolution, the width and height of the resolution are two-dimensional arrays. In the following figure, the left part indicates all images whose resolution is less than 2048 × 2048, and the right part indicates images whose resolution is less than 1024 × 1024 and images whose resolution is between 1024 × 1024 and 2048 × 2048. The two formats seem to be the same, but their value ranges are different.

Compilation and Execution

After setting related parameters, compile and build the project. During compilation, Hvigor obtains preset images based on configuration parameters, compresses them into textures using the transcoding component, and packs the textures. The following figure shows the switching effect of the tabs after texture compression.

As shown in the figure, when texture compression is used, images are displayed immediately when the screen switches to tab2, without any delay or white blocks.

Benefits and Overheads

When using texture compression to convert preset images, pay attention to the number of covered resource files to ensure that the overhead is minimized while maximizing the benefits. Therefore, the performance improvement of texture super-compression should be analyzed from both benefits and overheads.

Benefits

Texture compression converts preset images into texture formats, which are directly read by the GPU. This reduces the CPU and DDR load and speeds up image loading. The following figure shows the durations for reading a preset image in .png, .sut, and .astc formats.

The following table lists the durations for H:CreateImagePixelMap.

Expand

File

Duration

Benefits

.png

62.103ms

-

.sut

15.309ms

4.13 times

.astc

38.239ms

1.63 times

Loading a .png image takes roughly four times longer than loading a .sut image, while loading an .astc image takes about twice as long as loading a .sut image. When sut or astc is enabled, the preset images can be loaded more quickly.

After comparing the time required for loading images, switch tabs to check the memory usage before and after texture compression is enabled. The following figures show the related data.

The following table lists the memory usage before and after texture compression is enabled.

Expand

Whether To Enable Texture Compression

Memory Usage

Enabled (.sut)

165015KB

Enabled (.astc)

167723KB

Disabled

598965KB

The table shows that when texture compression is enabled, the memory usage decreases from 598,965 KB to 165,015 KB (.sut) or 167,723 KB (.astc), and the memory usage for image loading decreases significantly.

Overheads

When texture compression is used, preset images are converted during compilation, which increases the compilation duration. Once preset images are converted to the texture format, their size varies based on the image format, which may cause the package to expand or shrink.

The compilation takes a long time because it includes the texture compression process. You can use 87 preset PNG, WebP, and JPG images for compilation and package them in three scenarios: full compilation, modifying parameters of resolution, and adding 1 to 100 images. The following table lists the compilation time when texture compression is enabled and disabled.

Expand

Test Case

Texture Compression Disabled

Texture Compression Enabled

Added Time Consumption

Full compilation

19s 74ms

1min 16s

Traversing resource files, texture compression and moving resource files.

Modifying parameters of resolution

-

16s 487ms

Traversing and moving resource files.

Adding 1 to 100 images

10s 177ms~10s 283ms

16s 491ms~16s 673ms

Traversing resource files.

As shown in the preceding table, after texture compression is enabled, full compilation takes a longer time. However, reapplying texture compression after filtering preset images by resolution greatly shortens the compilation duration.

Analysis of several sample apps confirms that the expansion rate of .jpg and .webp images is two to three times. The following table lists the expansion rate data after texture super-compression is enabled.

Expand

Image Format

Expansion Rate

.jpg

3.05

.png

0.92

.webp

2.50

NOTE

The package body expansion rate varies depending on the resource size, format, resolution, and quantity of the app. The preceding data is for reference only.

After texture compression, the size of the .png image package remains unchanged, but the size of the .jpg and .webp image packages increases significantly. To optimize performance with texture super-compression in package size-sensitive scenarios, consider compressing all .png images into textures and selectively converting frequently used .jpg and .webp images or those critical to key frames.

Optimizing Non-Preset Image Loading

Non-preset images are not resources in the app. Instead, they are usually obtained from the network or local file system. These images are not fixed, for example, user profile pictures, images in dynamic content, and product images obtained from the server. The following describes several solutions for optimizing non-preset image loading before and during image use.

Compressing Images Using the Image Editing Tool

Before building an app, you are advised to use an image editing tool or script to adjust the image resolution to the actual display size in the UI and compress the image to reduce its size and improve the loading performance.

Reducing the Resolution of GIF Images

The FFmpeg third-party library provides the following two methods to reduce the resolution of GIF images. You can also combine the two methods.

Use the -s parameter to set the image resolution. For example, to reduce the resolution of a GIF image to 90 × 90 pixels, run the following command:
Collapse
Word wrap
Dark theme
Copy code
  1. ffmpeg -i input.gif -s 90x90 -y output.gif (set the width and height to 90 pixels.)

Alternatively, use the -vf parameter and the scale filter to set the width to 90 pixels and the height to be automatically scaled proportionally.

Collapse
Word wrap
Dark theme
Copy code
  1. ffmpeg -i input.gif -vf "scale=90:-1" -y output.gif

The parameters in the preceding commands are described as follows:

  • -s 90x90: sets the image resolution to 90 x 90 pixels.
  • -y: overwrites the existing file.
  • -vf "scale=90:-1": sets the image filter. The parameter is a single filter or a filter chain separated by commas (,).

Pre-compression Scenario Case

For example, directly scaling an image of 4180 × 4180 pixels to a profile of 80 × 80 pixels on a web page or app will cause high memory usage, slow decoding, and frame freezing. In this case, you are advised to compress and scale the image to a small image of 80 x 80 pixels before loading the image. The image completion delay is significantly different when the image is compressed and when the image is not compressed.

Time Consumption Comparison

Click to switch the test example and check the time consumption for reading images before and after compression. The following figures show the related data.

The following table lists the image decoding duration before and after the image is compressed to the actual UI size.

Expand

Whether the Pre-compression Is Performed

Image Decoding Duration

No

93ms

Yes

740us

The table shows that after the image is pre-compressed to the actual UI size, the image loading time decreases significantly from 183 μs to 95 μs.

Memory Usage Comparison

Click to switch the test example and check the memory usage before and after compression. The following figures show the related data.

The following table lists the memory usage before and after the image is compressed to the actual UI size.

Expand

Whether the Pre-compression Is Performed

Memory Usage

No

90224KB

Yes

21230KB

The table shows that after the pre-compression is performed, the memory usage for image loading decreases significantly from 90,224 KB to 21,230 KB.

Using CDN to Optimize Network Images

Optimizing network images helps improve user experience, reduce traffic consumption, reduce memory usage, and accelerate page rendering. Content Delivery Network (CDN) is a network technology that accelerates content distribution. Using CDN to crop images is an efficient way to optimize image loading performance. With the dynamic processing capability provided by CDN, you can adjust the image size, quality, and format as required, reducing bandwidth consumption and accelerating page loading.

How to Implement

Most CDN service providers (such as Huawei Cloud) allow you to dynamically adjust the image size and format by appending query parameters to the image URL. These parameters can control the width, height, and cropping mode of an image. The following are common parameters:

  • w: image width.
  • h: image height.
  • fit: cropping mode.
  • q: image quality.
  • format: output format (such as WebP and JPEG)

For example, use the cover cropping mode to convert the network image (URL: https://your-cdn-url.com/path/to/image.jpg) to a .webp image with a width of 200 pixels, height of 150 pixels, and quality of 85% (quality includes comprehensive indicators such as image definition) as follows:

Collapse
Word wrap
Dark theme
Copy code
  1. // It needs to be replaced with the image resource address required by the developer.
  2. private imgUrl = 'https://******.com/path/to/image.jpg?w=200&h=150&fit=cover&q=85&format=webp';
  3. build() {
  4. NavDestination() {
  5. Column() {
  6. Image(this.imgUrl)
  7. .width(200)
  8. .height(150)
  9. .objectFit(ImageFit.Cover)
  10. }
  11. .width('100%')
  12. .height('100%')
  13. }
  14. .backgroundColor('#F1F3F5')
  15. }
NOTE

Not all CDN services support the same parameters. For more information, see the documents provided by your CDN service provider.

Preferentially Using WebP Images

WebP supports both lossy and lossless compression. WebP images are smaller in size and can be transmitted at high quality, providing comprehensive functionalities and applicable to various scenarios.

Table 1 Advantages of WebP over PNG and JPG
Expand

Advantages

Description

Application Scenario

Smaller file size, faster loading, and less bandwidth

WebP images are 25% to 35% smaller than JPG images and 25% smaller than PNG images of the same quality.

Website images

Transparent channel supported

PNG images also support transparent channels, but WebP images are smaller.

UI icons, buttons, and transparent images

Animation supported

WebP images can replace GIF images with higher quality and smaller size.

Stickers

Using autoResize to Downsample the Image Component

autoResize is applicable to scenarios where the component size needs to be dynamically adapted. For example, when the page content changes or the device form (such as different screen sizes and the unfolded/collapsed state of a foldable screen) is different, the image needs to be automatically resized based on the size of the parent container. In this case, autoResize can be used to avoid image overflow or blank space, improving the UI adaptation capability. When autoResize is set to true for the Image component, the component determines the size of the image source used for drawing based on the size of the display area, which reduces the memory usage.

Collapse
Word wrap
Dark theme
Copy code
  1. Image(this.imageUrl)
  2. .width(300)
  3. .height(200)
  4. .autoResize(true)

Summary

The optimization policy varies depending on whether the image is preset (that is, packed in the app). For preset images, you are advised to use the texture compression technology. For non-preset images before use, you can compress them to the actual UI size, optimize network images, compress GIF images, and preferentially use WebP images. For non-preset images in use, you can use autoResize to optimize them. You need to select a proper solution or solution combination to optimize the image performance based on the actual situation.

Search in Best Practices
Enter a keyword.