去年接了一个电商小程序,上线后用户反馈"打开太慢"。用开发者工具一测,冷启动 3.5 秒,直接劝退。经过 6 步优化,压到 1.1 秒,转化率明显提升。把完整过程和代码分享出来。
背景与诊断
项目是 Taro + 原生混写,主包 2.1MB,首屏请求 8 个接口。用微信开发者工具「性能」面板分析:
- 主包体积过大,首屏加载时间长
- 首屏
setData数据量 120KB+,渲染卡顿 - 图片未懒加载,首屏请求 20+ 张图
- 未做数据预拉取,冷启动依赖串行请求
优化步骤
1. 分包加载(3.5s → 2.8s)
把非首屏页面和组件拆到分包:
// app.json
{
"pages": [
"pages/index/index",
"pages/cart/cart"
],
"subPackages": [
{
"root": "packageA",
"pages": [
"pages/product/detail",
"pages/order/list"
]
},
{
"root": "packageB",
"pages": [
"pages/user/center",
"pages/user/settings"
]
}
],
"preloadRule": {
"pages/index/index": {
"network": "wifi",
"packages": ["packageA"]
}
}
}
主包从 2.1MB 降到 980KB,首屏加载时间从 3.5s 降到 2.8s。
2. 首屏渲染优化(2.8s → 2.2s)
避免 setData 传大数据,分批更新:
// 错误:一次性 setData 120KB
this.setData({
list: hugeList,
banners: banners,
categories: categories
})
// 正确:分批、只传必要字段
this.setData({ banners: banners }) // 先渲染轮播
this.setData({ categories: categories }) // 再渲染分类
wx.nextTick(() => {
this.setData({
'list': list.map(item => ({
id: item.id,
name: item.name,
cover: item.cover,
price: item.price
}))
})
})
单次 setData 控制在 50KB 以内,首屏渲染从 2.8s 降到 2.2s。
3. 图片懒加载(2.2s → 1.8s)
用 IntersectionObserver 做自定义懒加载:
// components/lazy-image.js
Component({
data: { loaded: false, _observer: null },
attached() {
const observer = this.createIntersectionObserver()
observer.relativeToViewport({ bottom: 100 }).observe('.lazy-img', (res) => {
if (res.intersectionRatio > 0 && !this.data.loaded) {
this.setData({ loaded: true })
observer.disconnect()
}
})
},
detached() {
this.data._observer?.disconnect()
}
})
<!-- 使用 -->
<lazy-image src="{{item.cover}}" />
首屏图片请求从 20+ 降到 6 张,从 2.2s 降到 1.8s。
4. 数据预拉取(1.8s → 1.5s)
// app.js
App({
onLaunch() {
wx.setBackgroundFetchToken({
token: 'user_prefetch_v1'
})
}
})
服务端配置 backgroundfetch,在用户打开前预拉取首页数据。冷启动时部分数据已就绪,从 1.8s 降到 1.5s。
5. JS Bundle 优化(1.5s → 1.3s)
按需引入组件库,避免全量:
// 错误:全量引入
import Vant from 'vant'
import 'vant/lib/index.css'
// 正确:按需引入
import { Button, Cell, Toast } from 'vant'
import 'vant/lib/button/style'
import 'vant/lib/cell/style'
import 'vant/lib/toast/style'
主包 JS 从 420KB 降到 280KB,从 1.5s 降到 1.3s。
6. 缓存策略(1.3s → 1.1s)
// utils/cache.js
const CACHE_KEYS = {
USER_INFO: 'user_info',
CATEGORIES: 'categories',
CONFIG: 'app_config'
}
export function getCache(key, maxAge = 3600000) {
try {
const raw = wx.getStorageSync(key)
if (!raw) return null
const { data, time } = JSON.parse(raw)
if (Date.now() - time > maxAge) return null
return data
} catch {
return null
}
}
export function setCache(key, data) {
wx.setStorageSync(key, JSON.stringify({ data, time: Date.now() }))
}
首屏分类、配置等用缓存,减少首屏请求,从 1.3s 稳定到 1.1s。
优化效果汇总
| 步骤 | 优化项 | 启动时间 |
|---|---|---|
| 0 | 优化前 | 3.5s |
| 1 | 分包加载 | 2.8s |
| 2 | 首屏 setData 优化 | 2.2s |
| 3 | 图片懒加载 | 1.8s |
| 4 | 数据预拉取 | 1.5s |
| 5 | JS Bundle 按需 | 1.3s |
| 6 | 缓存策略 | 1.1s |
最终冷启动稳定在 1.1 秒左右,用户体感明显提升。
我是前端老兵AI,2016年入行,9年全场景前端工程师。专注 AI 编程提效 + 前端实战 + 副业变现。
📦 公众号搜索「前端老兵之AI」→ 后台回复「干货包」 免费领取:Cursor 完整配置模板(Vue3/React/Node 三套)+ AI 工作流手册 + 外包报价表
🎬 B站「前端老兵AI」 每周实操视频,比文章更直观
💬 点赞收藏,下次遇到直接翻出来用!评论区说说你踩过的坑,我会认真回复