Rendering Performance Optimization
1. Proper Handling of Scroll Events on Pages or Components
As long as the onPageScroll
listener is passed in during Page construction, the underlying framework assumes that developers need to listen to scroll events on the page. In this case, when the user scrolls the page, events are sent from the view layer to the logic layer at a high frequency, resulting in some communication overhead.
Similarly, for components like <scroll-view>
that can listen to scroll events using bind:scroll
, the same situation exists.
Due to the high frequency of scroll event triggers, developers may easily misuse it. When using scroll events, it's important to note:
- ✅ Avoid listening to scroll events unnecessarily.
- ❌ If scroll event listening is not needed, do not pass in an empty
onPageScroll
function during Page construction. - ❌ Avoid executing complex logic in scroll event listeners.
- ❌ Avoid frequent
setData
calls within scroll event listeners.
Page({
onPageScroll() {}, // ❌ Avoid retaining empty functions
});
Page({
// ✅ Simply omit the onPageScroll function
});
2. Choose High-Performance Animation Implementations
When developing interface animations, developers should choose high-performance animation implementations.
- ✅ Prioritize the use of CSS transitions, CSS animations, or other animation implementation methods provided by the mini-program framework to complete animations.
- ✅ In some complex scenarios where the above methods are not sufficient, dynamic adjustment of the node's style properties can be achieved through SJS responsive event handling to achieve animation effects. This approach can also dynamically generate animations based on user touch events.
- ❌ Avoid implementing animations by continuously calling
setData
to change the interface. Although this method is simple and flexible, it may lead to significant delays or stuttering, or even cause the mini-program to freeze.
3. Use <observe>
to Monitor Element Exposure
In some business scenarios, it may be necessary to monitor the exposure of elements for some page state changes or reporting and analysis purposes.
- ✅ It is recommended to use the
<observe>
node layout intersection status monitoring to infer whether certain nodes are visible and what proportion of them is visible. - ❌ Avoid using the
onPageScroll
event to continuously query node information through SelectQuery callbacks to determine element visibility.
4. Control the Number and Depth of DLT Nodes
A large DLT node tree will increase memory usage and also result in longer style reflow times, affecting user experience.
- ✅ It is recommended to have fewer than 1000 DLT nodes and a tree depth of fewer than 30 layers per page, with no more than 60 child nodes.
5. Control the Amount of Custom Data Passed in During Page Construction
For ease of development, developers can add arbitrary functions or data to the Object parameter passed into the Page constructor and access them within the page functions using this
. For example:
Page({
data: {},
userInfo: {}, // Custom data
currentUser: 'Transsion', // Custom data
onTap() {},
onLoad() {
console.log(this.currentUser);
},
});
To ensure that custom data is different instances across different page instances, the mini-program framework performs a deep copy of this data (excluding function-type fields) when the page is created. If there is too much or too complex custom data, it may result in significant overhead.
- ✅ For complex data objects, it is recommended to manually assign them to
this
during PageonLoad
or Componentcreated
instead of passing them as parameters during Page construction.
// ❌ Using complex objects as custom data
Page({
onLoad() {},
bigData: {
/* A complex object */
},
longList: [
/* A long complex array*/
],
});
// ✅ Manually assign at runtime to this. Developers can choose to perform deep copying, shallow copying, or no copying as needed.
Page({
onLoad() {
(this.bigData = {
/* A complex object */
}),
(this.longList = [
/* A long complex array*/
]);
},
});