小程序太慢被用户骂?我是这样优化的

去年我们公司的小程序被用户在应用商店评论区骂惨了:"卡得要死"、"加载半天"、"还不如网页版"...
作为主要开发者,我压力山大。花了 3 个月时间专门做性能优化,总算把用户评分从 2.1 分拉到了 4.3 分。
今天分享一下我在小程序性能优化上踩过的坑和总结出来的经验,希望能帮大家少走弯路。
我踩过的性能坑
第一个坑:代码包太大,启动慢得要命
刚开始做小程序时,我把所有功能都塞在主包里,结果代码包达到了 1.8M。用户打开小程序要等 5-6 秒,体验极差。
后来才知道微信有分包机制。我把非核心功能拆分到分包里,主包只保留首页和登录相关的代码,大小压缩到了 500K。启动时间从 6 秒降到了 2 秒。
具体做法:
- 把商城、个人中心、设置等模块拆分成独立分包
- 图片资源能放 CDN 的都放 CDN,不要打包到代码里
- 定期清理没用的组件和样式文件
第二个坑:setData 用法不当,页面卡顿
我以前习惯每次数据变化就调用一次 setData,结果页面经常卡顿。特别是列表页面,滚动时会明显感觉到掉帧。
后来学会了批量更新数据,把多次 setData 合并成一次。还有就是只更新变化的字段,不要整个对象都传。
血泪教训:
// 错误做法 - 频繁调用setData
this.setData({ loading: true });
this.setData({ userInfo: res.data });
this.setData({ loading: false });
// 正确做法 - 批量更新
this.setData({
loading: false,
userInfo: res.data,
});
第三个坑:网络请求没有缓存,重复加载
我们的小程序有个配置接口,每次进入页面都会请求一遍。后来发现这个配置基本不变,完全可以缓存起来。
现在我会把不常变的数据缓存到本地,设置合理的过期时间。用户体验提升很明显,特别是网络不好的时候。
现在我是怎么优化的
启动优化:让用户秒开你的小程序
分包策略:
- 主包只放首页、登录、基础组件
- 按业务模块拆分分包,比如商城、个人中心、活动页面
- 每个分包控制在 500K 以内
预加载优化:
- 在 app.json 里配置 preloadRule,用户浏览首页时预加载可能访问的分包
- 引导用户"添加到我的小程序",提高缓存命中率
代码优化:
- 开启懒加载:
"lazyCodeLoading": "requiredComponents"
- 压缩图片,能用 webp 就用 webp
- 删除 console.log 和无用代码
渲染优化:告别卡顿和白屏
setData 优化:
// 我现在的做法
const updateData = {};
if (needUpdateUser) updateData.userInfo = newUserInfo;
if (needUpdateList) updateData["list[0].status"] = "active";
if (Object.keys(updateData).length > 0) {
this.setData(updateData);
}
条件渲染优化:
- 初始不显示的内容用 wx:if,避免无意义的渲染
- 频繁切换的内容用 hidden,避免重复创建销毁
- 长列表使用虚拟滚动,我用的是 recycle-view 组件
骨架屏: 以前用户看到白屏会以为程序卡死了。现在我在所有需要加载数据的页面都加了骨架屏,用户体验好了很多。
网络优化:减少等待时间
缓存策略:
// 我的缓存工具函数
const cache = {
get(key) {
const data = wx.getStorageSync(key);
if (data && data.expireTime > Date.now()) {
return data.value;
}
return null;
},
set(key, value, expireMinutes = 30) {
wx.setStorageSync(key, {
value,
expireTime: Date.now() + expireMinutes * 60 * 1000,
});
},
};
请求优化:
- 合并接口:一个页面需要的数据尽量一个接口返回
- 预请求:在页面跳转前就开始请求下个页面的数据
- 失败重试:网络不好时自动重试,不要让用户手动刷新
用户体验优化
加载状态要明确
以前我经常忘记加 loading 状态,用户点击按钮没反应,会以为程序坏了。
现在我的习惯是:
- 所有异步操作都要有 loading 状态
- 按钮点击后立即显示 loading,防止重复点击
- 网络请求失败要有明确的错误提示
交互反馈要及时
震动反馈: 关键操作加上震动反馈,比如删除确认、支付成功等。代码很简单:
wx.vibrateShort({ type: "light" });
Toast 提示: 操作成功或失败都要给用户明确反馈,不要让用户猜。
空状态设计
以前列表为空时就显示个空白页面,用户体验很差。现在我会设计专门的空状态页面:
- 搜索无结果:显示"换个关键词试试"
- 网络异常:显示"网络开小差了,点击重试"
- 列表为空:显示"暂无数据,去看看别的吧"
一些实用的优化技巧
图片优化
懒加载:
// 使用intersection observer实现图片懒加载
const observer = wx.createIntersectionObserver();
observer.relativeToViewport().observe(".lazy-image", (res) => {
if (res.intersectionRatio > 0) {
// 开始加载图片
}
});
压缩和格式:
- 能用 webp 就用 webp,体积小很多
- 图片压缩到合适大小,不要用原图
- 小图标用字体图标或 SVG
内存管理
及时清理:
// 页面卸载时清理定时器和监听器
onUnload() {
if (this.timer) {
clearInterval(this.timer)
}
if (this.observer) {
this.observer.disconnect()
}
}
兼容性处理
机型适配:
- 低端机型降级处理,减少动画和特效
- 使用 wx.getSystemInfo 获取设备信息,针对性优化
- 刘海屏适配,使用 safe-area 相关样式
性能监控
现在我会在小程序里加一些性能监控:
// 启动时间监控
App({
onLaunch() {
this.launchTime = Date.now();
},
onShow() {
const showTime = Date.now();
console.log("启动耗时:", showTime - this.launchTime);
// 上报到后台
},
});
还会监控页面加载时间、接口响应时间等关键指标,及时发现性能问题。
写在最后
小程序性能优化是个持续的过程,不是一次性的工作。我现在的习惯是:
- 开发时就考虑性能:不要等出问题了再优化
- 定期检查:每个版本发布前都要测试性能
- 关注用户反馈:用户的抱怨往往指向真正的问题
- 数据驱动:用数据说话,不要凭感觉优化
经过这次优化,我们小程序的用户留存率提升了 30%,用户评分也从 2.1 分涨到了 4.3 分。虽然过程很痛苦,但结果还是很值得的。
希望我的经验对大家有帮助。如果你也遇到过类似问题,欢迎交流分享!
关注微信公众号

扫码关注获取:
- • 最新技术文章推送
- • 独家开发经验分享
- • 实用工具和资源
💬 评论讨论
欢迎对《小程序太慢被用户骂?我是这样优化的》发表评论,分享你的想法和经验