9.1 性能优化的方向
小程序的性能问题主要体现在两个维度:启动速度(用户第一次打开到可交互的时间)和运行时流畅度(滚动、动画、交互的顺滑程度)。
影响启动速度的因素
- 主包体积(代码 + 资源)
- 首页数据请求数量
- onLaunch 执行时间
- 首页组件复杂度
- 同步 Storage 读取阻塞
影响运行时流畅度的因素
- 频繁 setData(跨线程通信)
- setData 传输数据量过大
- 长列表不回收节点
- JS 主线程执行耗时任务
- CSS 动画触发重排/重绘
9.2 分包加载策略
分包是小程序性能优化最重要的手段之一。将非首屏必要的页面划分为独立分包,用户进入对应功能时才按需下载。
// app.json — 分包配置
{
"pages": [
"pages/index/index", // 主包:首页
"pages/profile/profile" // 主包:个人中心
],
"subpackages": [
{
"root": "pkgShop", // 商城分包
"name": "shop",
"pages": [
"pages/list/list",
"pages/detail/detail",
"pages/cart/cart"
]
},
{
"root": "pkgSettings", // 设置分包
"name": "settings",
"independent": true, // 独立分包:不依赖主包,可从分享直接进入
"pages": [
"pages/settings/settings",
"pages/about/about"
]
}
],
// 分包预下载:在某些页面停留时,提前下载分包
"preloadRule": {
"pages/index/index": {
"network": "wifi", // 仅 WiFi 下预下载
"packages": ["shop"]
},
"pages/profile/profile": {
"network": "all",
"packages": ["settings"]
}
}
}
独立分包(independent)
设置 "independent": true 的分包是独立分包,它不依赖主包代码,可以独立运行(如从分享链接直接进入商品详情页,不需要先加载主包)。代价是:独立分包中无法访问 app.js 的 globalData 和 App 生命周期,需要自行处理初始化逻辑。
9.3 首屏加载优化
// 优化策略 1:数据预拉取(小程序启动时提前请求数据)
// 在公众平台「开发 → 数据预拉取」配置预拉取 URL
// 在 onLaunch 中读取预拉取的数据
onLaunch() {
wx.getBackgroundFetchData({
fetchType: 'pre', // 'pre' 定期预拉取 / 'periodic' 周期性
success(res) {
// res.fetchedData: 预拉取的数据(string)
if (res.fetchedData) {
const data = JSON.parse(res.fetchedData)
// 缓存到内存,首页直接使用
getApp().prefetchedData = data
}
}
})
}
// 优化策略 2:骨架屏(Skeleton Screen)
// 在数据加载完成前显示骨架占位
Page({
data: { loaded: false, list: [] },
async onLoad() {
const list = await fetchList()
this.setData({ list, loaded: true })
}
})
<!-- 骨架屏 WXML -->
<view wx:if="{{!loaded}}">
<view wx:for="{{[1,2,3,4,5]}}" wx:key="*this" class="skeleton-item">
<view class="skeleton skeleton-image"/>
<view class="skeleton skeleton-title"/>
<view class="skeleton skeleton-text"/>
</view>
</view>
<view wx:else>
<<!-- 真实内容 -->>
</view>
9.4 长列表优化
<!-- recycle-view:虚拟列表组件,只渲染可见区域节点 -->
<!-- 需要在 app.json 中引入:@miniprogram-component-plus/recycle-view -->
<recycle-view
batch="{{batchSetRecycleData}}"
id="recycleId"
>
<recycle-item
wx:for="{{recycleList}}"
wx:key="id"
>
<product-card product="{{item}}"/>
</recycle-item>
</recycle-view>
9.5 worklet 动画
worklet 是 Skyline 渲染引擎提供的动画机制,代码直接运行在渲染线程,无需跨线程通信,实现真正的 60fps/120fps 动画。
worklet 函数
用
'worklet' 指令标记的函数,在渲染线程执行,可以直接读写 SharedValue 而不需要跨线程SharedValue
逻辑层和渲染层共享的响应式值,类似 React Native 的 Animated.Value,修改时自动触发动画
applyAnimatedStyle
将 SharedValue 绑定到组件样式,由渲染线程直接驱动样式变化,不经过逻辑层
// worklet 动画示例:拖拽卡片
Page({
onLoad() {
// 创建共享值(初始位置)
this.translateY = wx.worklet.shared(0)
// 将 SharedValue 绑定到样式
this.applyAnimatedStyle('#draggable-card', () => {
'worklet'
return {
transform: `translateY(${this.translateY.value}px)`
}
})
},
// 触摸事件处理(手势驱动动画)
handleTouch: function(e) {
'worklet' // 此函数在渲染线程执行!
const ty = e.touches[0].pageY - e.touches[0].startY
this.translateY.value = ty
},
// 松手后弹簧回弹
handleTouchEnd: function() {
'worklet'
this.translateY.value = wx.worklet.spring(0, {
mass: 1,
stiffness: 200,
damping: 20
})
}
})
9.6 Skyline 共享元素动画
共享元素动画(Shared Element Transition)是 Skyline 的明星特性,实现页面跳转时元素平滑过渡(类似 iOS 的 Hero 动画)。
<!-- 列表页 list.wxml -->
<view
wx:for="{{products}}"
wx:key="id"
bindtap="goDetail"
data-id="{{item.id}}"
>
<!-- shared-element-root 标记共享元素容器 -->
<!-- share-key 是元素在两个页面间的唯一标识 -->
<image
src="{{item.cover}}"
mode="aspectFill"
class="product-thumb"
data-share-key="product-cover-{{item.id}}"
/>
</view>
<!-- 详情页 detail.wxml -->
<image
src="{{product.cover}}"
mode="aspectFill"
class="product-cover"
data-share-key="product-cover-{{productId}}"
/>
// 配置 Skyline 路由动画
// detail.json
{
"renderer": "skyline",
"pageStyle": "bottom-sheet", // 底部弹出动画
"navigationStyle": "custom"
}
// 或者使用 wx.navigateTo 时传入路由动画类型
wx.navigateTo({
url: '/pkgShop/pages/detail/detail?id=123',
routeType: 'zoom-fade-out' // 缩放淡出动画
})
9.7 声明式手势系统
Skyline 提供了声明式手势识别系统,解决了 WebView 时代手势冲突难处理的痛点:
<!-- 手势冲突解决:scroll-view 内的可拖拽卡片 -->
<scroll-view scroll-y>
<!-- pan-gesture: 拖拽手势 -->
<pan-gesture-handler
worklet:ongesture="onPan"
simultaneous-handlers="{{['scroll']}}"
>
<view class="draggable">可拖拽元素</view>
</pan-gesture-handler>
</scroll-view>
<!-- 双指缩放 -->
<scale-gesture-handler worklet:ongesture="onScale">
<image src="{{photoUrl}}" class="photo"/>
</scale-gesture-handler>
9.8 使用 DevTools 分析性能
微信开发者工具内置了强大的性能分析工具:
- Audits 面板:自动检测小程序的性能问题,给出具体优化建议
- Performance 面板:录制运行时性能,查看帧率、CPU 使用、setData 调用频次
- Network 面板:分析网络请求时间和资源大小
- wxml 面板:查看真实渲染树结构,排查节点过多问题
体验评分
微信开发者工具的 Audits 面板会对你的小程序进行体验评分(0-100分),并按类别列出问题:包大小、渲染性能、网络请求、合规性等。建议发布前确保评分在 85 分以上。体验评分也会影响微信搜索排名。