How it works
The architecture for running Mini Programs is different from the architecture for running traditional HTML5 applications and consists of two parts: WebView and Worker. WebView is responsible for rendering. Worker is responsible for storing data and executing business logic.
- The communication between WebView and Worker is asynchronous. This means that when you call the setData method, the data is asynchronously transferred from Worker to WebView instead of being immediately rendered.
- Data needs to be serialized into strings before being transferred by using
evaluateJavascript
. The size of data affects the transfer performance.
Optimize the first screen
The definition of the first screen may differ. In this case, the first screen refers to the first page that is meaningfully rendered from the perspective of business logic. For example, for a list page, the first screen refers to the content that is rendered from the list for the first time.
Limit the size of the resource package of a Mini Program
When a user opens a Mini Program, Alipay downloads the resource package of the Mini Program from the relevant content delivery network. The size of the resource package affects the startup performance of the Mini Program.
Optimization suggestions:
- Regularly delete useless image resources. By default, all image resources are included in the resource package.
- Limit the sizes of images. We recommend that you do not include large images in the resource package and that you upload large images by using a content delivery network.
- Regularly clear useless code.
Use onLoad to request data in advance.
- When a Mini Program is running, the lifecycle function “onLoad” is triggered on a page. Then, the initial page data is transferred from Worker to WebView for initial rendering.
- After the initial rendering is complete, a notification is sent from WebView to Worker and the lifecycle function “onReady” is triggered.
For specific Mini Programs, a request for data may be included in the “onReady” function, which slows down the rendering of the first screen.
Optimization suggestion: Use onLoad to request data in advance.
Limit the number of nodes on the first screen that can be rendered at a time
Generally, after a business request receives a response, the setData method triggers to re-render the page. The execution process is described as follows:
- Data is transferred from Worker to WebView.
- On WebView, a virtual DOM is constructed based on the transferred data, and the virtual DOM is compared against the original DOM from the root node. Then, the rendering starts.
Data needs to be serialized for the communication between Worker and WebView. After the data is transferred to WebView, evaluateJavascript
is executed. Therefore, if the volume of data transferred at a time is excessively large, the rendering performance of the first screen is affected.
There may be excessive nodes on WebView or the file structure has excessive directories. For example, the list page of a Mini Program may render more than 100 list items at a time. Each list item contains embedded content. However, only less than 10 list items are displayed on the screen. This causes the comparison to take more time. In addition, due to the fact that this is the rendering of the first screen, a lot of DOMs may be constructed, which affects the rendering performance of the first screen.
Optimization suggestions:
- Limit the volume of data when you call the setData method. This helps avoid transferring an excessively long list at a time.
- Do not create excessive nodes for the first screen. The server may request a large volume of data at a time. In this case, do not specify all the data when you call the setData method. You can specify some of the data and wait a specific period of time, such as 400 ms. The specific period of time varies based on your business. Then, you can call the
$spliceData
method to transfer the rest of the requested data.
Optimize the logic of the setData method
A change on a page triggers the setData method. Multiple changes on a page may trigger the setData method at the same time to re-render the page. Each of the following interfaces triggers the re-rendering of the WebView of a page:
Page.prototype.setData
: triggers the comparison of the whole page.Page.prototype.$spliceData
: used for a long list to avoid transferring the whole list and triggering the comparison of the whole page every time.Component.prototype.setData
: triggers the comparison from the relevant component node.Component.prototype.$spliceData
: used for a long list to avoid transferring the whole list every time and trigger the comparison from the relevant component node.
Optimization suggestions:
- Do not frequently trigger the setData or
$spliceData
method on a page or in a component. Some pages may contain countdown logic. However, the countdown logic may have an excessively high frequency that causes millisecond-level triggering. - If you need to frequently trigger re-rendering, do not call the setData or
$spliceData
method on the page. Instead, package the relevant resources into a custom component and call the setData or $spliceData method in the component for re-rendering. - For the rendering of long list data, use
$spliceData
to add data for multiple times. You do not need to transfer the whole list at one time. - For a complex page, we recommend that you package the relevant resources into a custom component to avoid calling the setData method on the page.
Optimization example:
We recommend that you set data in a specified path, as shown in the following code snippet:
this.setData({
'array[0]': 1,
'obj.x':2,
});
Do not use the following code. In the code, this.data
is copied, but the attributes are modified.
const array = this.data.array.concat();
array[0] = 1;
const obj={...this.data.obj};
obj.x=2;
this.setData({array,obj});
Do not directly modify the data that is obtained by using this. data
, as shown in the following code snippet. This breaches the principle of data integrity.
this.data.array[0]=1;
this.data.obj.x=2;
this.setData(this.data)
Use the $spliceData
method for long lists, as shown in the following code:
this.$spliceData({ 'a.b': [1, 0, 5, 6] })
onPageScroll
event. When the event is triggered, the component needs to be notified and start re-rendering. The following code snippets show how to implement this process:
// /pages/index/index.js
Page({
onPageScroll(e) {
if (this.xxcomponent) {
this.xxcomponent.setData({
scrollTop: e.scrollTop
})
}
}
})
// /components/index/index.js
Component({
didMount(){
this.$page.xxcomponent = this;
}
})
You can bind the component to the page in the didMount() method. When you call the component-level setData method from the page, the call only triggers the re-rendering of the component.
Use the key parameter
You can use the key parameter in for
to improve performance.
Code sample:
<view a:for="{{array}}" key="{{item.id}}"></view>
<block a:for="{{array}}"><view key="{{item.id}}"></view></block>