Recently, I have been working on optimizing the cold start time of WeChat mini programs. After consulting the official documentation of mini programs, I found that it has been written in great detail. Here, I will make a record and summary, highlighting the parts that developers should pay attention to.
Start Definition#
From "User opens the mini program" to "Home page rendering completed".
The sign of "Home page rendering completed" in the mini program is the triggering of the first page Page.onReady
event. Due to the differences in the startup process, the "Home page rendering completed" defined by the mini program is not equivalent to the browser's DOMContentLoaded
or load
event.
Startup Process and Time Impact#
From opening the WeChat mini program to displaying the home page, the following processes need to be experienced:
The processes are not serial, and they will be parallel as much as possible. The total startup time cannot be simply calculated by adding up the stages.
Resource Preparation#
Preparation of Mini Program-related Information
When users first access the mini program, when the mini program version is updated, or when a mini program that has not been used for a long time is used, the WeChat client needs to obtain basic information about the mini program from the WeChat backend, such as avatar, nickname, version, configuration, permissions, etc., in order to perform necessary version management, permission control, and verification on the mini program.
In order to minimize the impact on startup time while ensuring the real-time nature of the information, this information will be cached locally and updated through certain mechanisms.
When a new version of the mini program is released, it will cause an increase in the proportion of synchronous requests required during startup, which in turn will increase the average startup time. Therefore, it is recommended that developers reasonably plan version releases.
Environment Preparation
The running environment of the mini program includes the mini program process, system components and UI elements of the client's native part (such as navigation bar, tabBar, etc.), the WebView
container used for rendering pages, the runtime environment of the developer's JavaScript
code, the mini program basic library, etc.
Some environments (such as the JavaScript
engine and the mini program basic library) need to be prepared before executing the mini program code, while others will be performed in parallel during the startup process.
In order to minimize the impact of environment preparation on startup time, the WeChat client will preload the running environment before the mini program starts according to the user's usage scenario and the usage of device resources, according to a certain strategy.
Code Package Preparation
When users first access the mini program or when the mini program version is updated, the code package address needs to be obtained from the WeChat backend based on the page the user is accessing, and the mini program code package needs to be downloaded from the CDN and verified. Depending on the subpackage where the mini program page is located and the plugins used, multiple code packages or plugin packages may need to be downloaded for one startup.
In addition to the startup process, code package downloads will also be triggered during page navigation, pre-downloading, and asynchronous loading of subpackages processes.
In order to minimize the impact on startup time while ensuring that users can access the new version as much as possible, the mini program code package will be cached locally and updated through certain mechanisms. In order to reduce the download time of code packages, WeChat also uses methods such as code package compression, incremental updates, more efficient network protocols, CDN pre-connection, code package reuse, etc.
Considering the impact of package size on user experience, the platform limits the maximum size of a single mini program code package to 2M. In order to ensure startup speed, developers should control the size of code packages used during startup as much as possible. Specific methods can be found in 《Code Package Size Optimization》.
Mini Program Code Injection (Logic Layer)#
When the mini program starts, it needs to read the configuration and code of the mini program from the code package and inject it into the JavaScript
engine. During the main package code injection process, the App.onLaunch
and App.onShow
lifecycles of the mini program will be triggered. If the mini program uses plugins or extension libraries, the corresponding plugin and extension library code will be injected before injecting the developer's code.
On some platforms, the WeChat client uses the Code Caching technology of the V8 engine to cache the compilation results of the code, reducing the compilation time when it is injected for the second time.
Since the "Home page rendering" requires data sent from the logic layer, if the code injection process takes too long, it will delay the start of "Home page rendering". It is recommended that developers refer to the 《Code Injection Optimization》 section for optimization.
Mini Program Code Injection (View Layer)#
The developer's WXSS
and WXML
will be compiled into JavaScript
code and injected into the view layer, including the page structure and style information required for page rendering.
The injection of mini program code in the view layer and the logic layer is performed in parallel.
Since the "Home page rendering" requires the page structure and style information of the view layer, if the code injection process takes too long, it will affect the time for rendering data to reach the view layer, thereby affecting the rendering time of the "Home page".
Although developers cannot directly modify the JS code generated by the view layer, they can reduce this part of the time-consuming process by using methods such as "lazy loading" and removing unused custom components.
Home Page (Initial) Rendering#
After the logic layer code injection of the mini program is completed, the mini program framework will initialize the page component tree and send the initial data to the view layer based on the page the user is accessing, and then trigger the Page.onLoad
and Page.onShow
lifecycles of the home page in order.
After completing the injection of the view layer code and receiving the initial data sent from the logic layer, combined with the initial data and the page structure and style information obtained from the view layer, the mini program framework will render the home page of the mini program, display the first screen of the mini program, and trigger the Page.onReady
event of the home page, marking the completion of the mini program startup process.
The rendering time of the home page is the last part of the startup process and directly affects the startup time of the mini program. The length of time is related to the complexity of the page structure and the number of custom components involved in rendering. It is recommended that developers refer to the 《First Screen Rendering Optimization》 section for optimization.
If "lazy loading" is enabled, the injection of some component code will be delayed until this stage, which will cause an increase in the stage time, but the total time will generally decrease.
First Screen Content Display#
After the "Home page rendering" is completed, the mini program startup process is completed, the loading disappears, and in general, users should be able to see the first screen content immediately at this time. If it depends on network requests, it needs to wait for setData to update the page before it can be displayed. A "skeleton screen" can be displayed first to avoid a blank screen and optimize the user experience.
The display of the first screen content triggered by asynchronous setData may not be included in the startup time statistics, but it will delay the time for users to see the page content and affect the user experience. It is recommended that developers refer to the 《First Screen Rendering Optimization》 section for optimization.
Optimization Strategies#
In the mini program startup process, the time-consuming processes of code package preparation, mini program code injection, and home page rendering are related to the mini program itself. Developers can optimize their work from the following aspects:
- Code Package Size Optimization
- Subpackage loading, independent subpackage, asynchronous subpackage
- Pay attention to the fact that ordinary subpackages cannot refer to each other, and asynchronous subpackage loading can be used to solve this problem.
- Independent subpackages do not need to download the main package and cannot depend on the main package.
- Avoid unnecessary global custom components and plugins
- Control the resources in the code package: use CDN to import images
- Timely clean up unused code and resources: use the code static dependency analysis provided by the developer tools
- Subpackage loading, independent subpackage, asynchronous subpackage
- Code Injection Optimization
- Use on-demand injection and injection on demand: combined with avoiding unnecessary global custom components and plugins
- Reduce synchronous API calls during startup: in the mini program initialization code (content outside the Page and App definitions) and the
App.onLaunch, App.onShow, Page.onLoad, Page.onShow
lifecycles, avoid blocking the current JS thread - Reduce complex calculations during startup: same as above
- First Screen Rendering Optimization
- Enable on-demand injection and injection on demand: reduce the number of components that need to be initialized
- Enable initial rendering cache: skip the logic layer initialization process for the second startup
- Avoid referencing unused custom components
- Simplify first screen data: try not to put data unrelated to view layer rendering in
data
- Request first screen data in advance: initiate network requests in
Page.onLoad
or earlier - Cache request data locally:
wx.setStorage
,wx.getStorage
- Skeleton screen
- Other Optimization Suggestions
- Control the frequency of version releases