本文旨在介绍两点在小程序开发过程当中碰到的一些性能问题以及 WePY 的一些优化方案。
性能调优是一个亘古不变的话题,无论是在传统H5上还是小程序中。因为实现机制不同,可能导致传统H5中的某些优化方式在小程序上并不适用。因此必须另开辟蹊径找出适合小程序的调估方式。
传统H5中也可以通过预加载来提升用户体验,但在小程序中做到这一点实际上是可以更简单方便却又更容易被忽视的。
传统H5在启动时,page1.html 只会加载 page1.html 的页面与逻辑代码,当page1.html 跳转至 page2.html 时,page1 所有的 Javascript 数据将会从内存中消失。page1 与 page2 之间的数据通信只能通过 URL 参数传递或者浏览器的 cookie,localStorge 存储处理。
小程序在启动时,会直接加载所有页面逻辑代码进内存,即便 page2 可能都不会被使用。在 page1 跳转至 page2 时,page1 的逻辑代码 Javascript 数据也不会从内存中消失。page2 甚至可以直接访问 page1 中的数据。
最简单的验证方式就是在 page1 中加入一个 setInterval(function () {console.log('exist')}, 1000)。传统H5中跳转后定时器会自动消失,小程序中跳转后定时器仍然工作。
小程序的这种机制差异正好可以更好的实现预加载。通常情况下,我们习惯将数据拉取写在 onLoad 事件中。但是小程序的 page1 跳转到 page2,到 page2 的 onLoad 是存在一个 300ms ~ 400ms 的延时的。如下图:
因为小程序的特性,完全可以在 page1 中预先拿取数据,然后在 page2 中直接使用数据,这样就可以避开 redirecting 的 300ms ~ 400ms了。如下图:

在官方demo中加入两个页面:page1,page2
-
// page1.js 点击事件中记录开始时间
-
bindTap: function () {
-
wx.startTime = +new Date();
-
wx.navigateTo({
-
url: '../page2/page2'
-
});
-
}
-
-
-
// page2.js 中假设从服务器拉取数据需要500ms
-
fetchData: function (cb) {
-
setTimeout(function () {
-
cb({a:1});
-
}, 500);
-
},
-
onLoad: function () {
-
wx.endTime = +new Date();
-
this.fetchData(function () {
-
wx.endFetch = +new Date();
-
console.log('page1 redirect start -> page2 onload invoke -> fetch data complete: ' + (wx.endTime -wx.startTime) + 'ms - ' + (wx.endFetch - wx.endTime) + 'ms');
-
});
-
}
重试10次,得到的结果如下:

对于上述问题,WePY 中封装了两种概念去解决:
-
预加载数据
用于 page1 主动传递数据给 page2,比如 page2 需要加载一份耗时很长的数据。我可以在 page1 闲时先加载好,进入 page2 时直接就可以使用。
-
预查询数据
用于避免于 redirecting 延时,在跳转时调用 page2 预查询。
扩展了生命周期,添加了onPrefetch事件,会在 redirect 之时被主动调用。同时给onLoad事件添加了一个参数,用于接收预加载或者是预查询的数据:
-
// params
-
// data.from: 来源页面,page1
-
// data.prefetch: 预查询数据
-
// data.preload: 预加载数据
-
onLoad (params, data) {}