做小程序这几年,被问得最多的问题不是“怎么加功能”,而是“为什么我的小程序用起来有点卡”。说实话,卡顿这东西很玄学,用户不会告诉你具体哪里卡,他只会默默退出。今天就聊聊我踩过的几个坑,都是些不起眼但很要命的细节。

首屏加载:别让用户盯着白屏发呆
很多人一上来就优化接口,其实首屏最大的问题往往在包体积。微信小程序主包限制 2MB,超了就得分包,但分包不是万能药。我的习惯是:
- 把非首屏的页面、组件、图片全部分出去,主包只留 tabBar 页面和公共依赖
- 图片别直接扔本地,能上 CDN 就上 CDN,本地图片用
webp格式,体积能小一半 - 首屏接口能并行的别串行,用
Promise.all一把梭
还有个容易被忽略的点:app.js 里的 onLaunch 别干重活。我见过有人在里面同步读缓存、初始化一堆 SDK,结果首页都渲染完了它还在跑。这些逻辑能延后就延后,放到页面 onLoad 里按需执行。
setData 是个双刃剑
小程序的数据驱动全靠 setData,但它也是性能杀手。几个原则我基本刻在脑子里了:
- 单次
setData数据别超过 1MB,超了微信直接给你警告 - 别把整个列表重新 set 一遍,用路径更新,比如
this.setData({ 'list[0].name': 'x' }) - 频繁触发的场景(滚动、输入)加节流,不然逻辑层和视图层通信能把手机烫死
// 错误示范:每次输入都全量更新
onInput(e) {
this.setData({ list: this.data.list.map(...) })
}
// 正确姿势:只更新变化的那一项
onInput(e) {
const index = e.currentTarget.dataset.index
this.setData({ [`list[${index}].value`]: e.detail.value })
}另外,setData 的回调里别做耗时操作,它是在视图层更新完之后才触发的,你在这里再 set 一次,很容易形成循环。
图片和长列表:用户感知最明显的地方
图片这块,lazy-load 一定要开,尤其是列表页。还有 mode 属性,widthFix 虽然方便但会触发重排,能确定尺寸就用固定宽高。长列表超过 100 条,老老实实做虚拟列表或者分页,别一次性渲染,不然低端机直接卡成 PPT。
我有个客户的小程序,商品列表一页渲染 500 条,用户反馈“滑不动”。后来改成每次 20 条 + 触底加载,投诉立马没了。优化有时候不是技术活,是产品活。
交互反馈:让用户知道“我在干活”
网络慢的时候,最怕用户以为按钮没反应,然后疯狂点击。我的做法是:
- 提交类按钮点击后立刻
disabled,配合wx.showLoading - 列表加载用骨架屏,比转圈圈体感好很多
- 操作成功给个轻提示,别让用户猜
这些细节花不了多少代码,但对“顺滑感”的提升特别明显。用户体验这东西,往往就是这些不起眼的小地方堆出来的。
最后说两句
小程序优化没有银弹,核心就一句话:站在用户的角度想,他在哪一步会不耐烦。把那个点找出来解决掉,比盲目堆优化手段有用得多。下次再聊具体怎么用开发者工具的性能面板定位问题,那个更硬核。

评论 (0)
还没有评论,快来抢沙发吧~