HomeDocs
跳到主要内容

内存优化

1. 小程序常见的内存泄露问题

存在内存泄露问题会导致小程序在运行过程中内存占用持续增长,引起小程序闪退或被强制销毁。

1.1 小程序长期持有页面实例,导致页面实例和引用的组件无法正常销毁

页面 unload 之后,基础库会从页面栈中将页面实例清理。正常情况下,JS 垃圾回收机制会将页面进行回收,释放内存。

但如果开发者代码中持有的页面实例(this)未释放,则会导致页面未被正常回收,引起内存泄露。建议开发者注意,并在 unload 中进行必要的清理。

案例一:页面实例被未解绑的事件监听引用

事件监听器中持有了页面的 this,如果页面销毁后监听未解绑,会导致页面无法释放。

Page({
keyboardChangeHandler({ height }) {
this.setData({ height });
},
onLoad() {
this._handler = this.keyboardChangeHandler.bind(this);
dlt.onKeyboardHeightChange(this._handler);
},
// 修复方法:unload 中解绑监听
// onUnload() {
// dlt.offKeyboardHeightChange(this._handler)
// },
});

案例二:页面实例被页面外变量或全局变量引用

函数闭包内持有了页面的 this,且函数被挂到全局或页面声明周期外的变量,会导致页面无法释放。

let languageListener = null;

Page({
onLoad() {
getApp().userInfoChangeListener = ({ userName }) => {
this.setData({ userName });
};
languageListener = ({ lang }) => {
this.setData({ lang });
};
},
// 修复方法:unload 中进行清理
// onUnload() {
// getApp().userInfoChangeListener = null
// languageListener = null
// },
});

案例三:页面实例被异步回调长时间引用

如果在长时间未返回的异步回调中访问了页面的 this,如持续时间过长的 setTimeout、setInterval,耗时较长的 dlt API 回调(如长时间的 dlt.request 等),会导致页面无法释放。

Page({
onLoad() {
this._timer = setInterval(() => {
this.setData({
timerValue: Date.now(),
});
}, 1000);
},
// 修复方法:unload 中进行清理
// onUnload() {
// clearInterval(this._timer)
// },
});

1.2 事件监听未及时解绑

事件监听结束后,应及时解绑监听器

1.3 未清理的定时器

开发者在开发如「秒杀倒计时」等功能时,可能会使用 setInterval 设置定时器,页面或组件销毁前,需要调用 clearInterval 方法取消定时器。

Privacy agreementDeveloper agreementcontact us: developer_service.mi@transsion.com © 2024 MiniApp. All Rights Reserved.