
做小程序这几年,被问得最多的一个问题:为什么我的小程序这么卡。
卡的原因翻来覆去就那几个 —— 包体超了、setData 用猛了、接口串着调、启动链路太长。单拎出来都不难,难的是不知道先弄哪个,改了一通发现白屏还在。
我们按实际踩坑的顺序来:先砍包体,再弄首屏,接着处理数据更新,最后补监控。这个顺序别乱,乱了容易白忙。
一、先把包体砍下来

微信小程序主包和单个分包上限 2M,整个小程序 20M。这条硬限制卡死过不少项目。我们接过一个,主包超了传不上去,一查,问题全在主包:页面不分包全塞进去、图片没走 CDN 本地打包、组件库全量引入其实就用了一两个组件。
分包不是可选项,是必做的。tabBar 页面留主包,其他页面按业务拆。新手容易栽的一个细节:分包之间公共代码要抽到主包,不然每个分包都打包一份公共库,总包越拆越大。
{
"pages": ["pages/index/index", "pages/mine/mine"],
"subPackages": [
{ "root": "pages/order", "pages": ["order/list", "order/detail"] },
{ "root": "pages/mall", "pages": ["mall/home", "mall/goods"] }
],
"preloadRule": {
"pages/index/index": {
"network": "all",
"pages": ["pages/order/order-list"]
}
}
}preloadRule 记得配。用户点进 tab 的时候,该去的分包已经悄悄拉下来了,体感就是秒开。network 别只设 wifi,用户流量没那么金贵,体验要紧。
包体瘦下来,启动也跟着快。小程序冷启动的 JS 代码注入是按代码量算时间的,代码少了,注入就快。光这一项,能顶掉一半的启动优化。
二、首屏白屏,一半是自找的

排查下来,首屏白屏的根因基本三种:onLaunch 或 onLoad 里干了重活、首屏接口串行调用、页面引了大图或 base64 图。前两种最常见。
接口能并行就并行。有个首页,三个接口本来串着调,最后一个要等快一秒,页面就干等。改成 Promise.all 之后,首屏明显快了一大截。这个改动成本最低、收益最直接,建议先做。
骨架屏该上上,但别指望它解决慢的问题。它解决的是丑的问题 —— 白屏不好看。内容出来的速度,还是得靠上面这些实打实的改动,顺序反了就是自欺欺人。
三、setData 这个坑,真机才会暴露

setData 是小程序逻辑层和视图层通信的通道,数据量大就卡。我们有个列表页,一次刷新把整个数组 setData 一遍,上千条数据,真机划两下就开始掉帧。
最气人的是,这种问题在开发者工具里怎么测都是好的,一到真机就现形。排查的时候先怀疑 setData,别先怀疑网络。
setData 就记三条:只传变化的部分;大列表分页追加;高频更新的别走 setData,用 WXS 或 CSS 动画。
// 别这么写:整表更新
this.setData({ list: newList })
// 这样写:只更新变化的项
this.setData({ [`list[${index}].status`]: newStatus })四、弱网这块,别只怪网络

接口能合并的合并,详情页的基础信息和用户信息,一次拿完别分两次。再给 Storage 加一层缓存兜底,网络挂了先渲染上次的数据,用户至少看到东西,不是转圈转到放弃。
请求超时别用默认的 60 秒,弱网下没人等那么久。该失败就失败,早点给用户反馈,比干等着强。
五、监控这关别省
不夸张地说,没监控的小程序等于裸奔。线上真机什么情况,本地永远测不出来。小程序有现成的错误监听和性能上报,接上之后先盯四个数:首屏耗时、启动耗时、接口失败率、JS 错误率。配上告警,用户还没开口,问题你已经知道了。
优化做到这份上,大部分卡顿都能解决。剩下的基本是业务自己的问题 —— 比如页面非得一次渲染上千条数据,那谁也救不了。工具能做的就这么多,业务不合理,再好的优化都是擦屁股。
在线
电话
微信
需求
TOP