Skip to content

UniApp 性能优化清单:启动速度、包体积与渲染 ​

结论先行:UniApp 性能优化遵循"先测量、再动手"的顺序,三个高收益方向按投入产出排序:分包加载与静态资源治理(动一次配置,主包常能缩 30% 以上)、setData 批量化与长列表虚拟化(解决滚动卡顿)、启动链路瘦身(首屏快 1~2 秒)。90% 的"卡"来自频繁的细粒度数据更新和超长页面节点数,先解决这两个,再谈更深的优化。

先测量:3 个指标与对应工具 ​

不测量就优化,等于蒙眼开车。先记录三个基线指标:

  1. 启动到首屏时间:微信开发者工具"性能面板/体验评分"可测小程序启动与首屏耗时;APP 端用真机运行日志中页面 onLoad 与 onReady 时间差估算。
  2. 包体积:微信开发者工具构建后查看主包与各分包大小(主包上限 2MB,整包上限与平台版本相关,以官方文档为准)。
  3. 滚动帧率:开发者工具真机调试的性能火焰图,或 Android 端开启 GPU 过渡绘制检测辅助定位。

把三个数字写进优化文档,每完成一项就复测,用数据验收而不是凭感觉。

启动速度:4 个高收益动作 ​

  1. 首页做减法:首屏只渲染视口内的核心内容,轮播图、推荐流等模块延迟加载。检测方法:注释掉首页一半模块看首屏时间变化,通常能定位出 50% 以上的耗时来源。
  2. 数据请求并行化与前置:把首页依赖的多个接口合并为一次聚合请求,或在 App onLaunch 预发起请求,页面 onLoad 直接消费。串行改并行常常直接省 300~500ms。
  3. 关闭 splash 延迟:manifest 中配置自动关闭 splash(App 端),避免白屏等待叠加。
  4. 分包预下载:核心路径的下一页分包配置 preloadRule 预下载,点击时秒开。检测:分包下载耗时在小程序后台"开发"板块可见。

包体积:分包与资源治理 ​

包体积影响下载转化率与启动速度,治理三板斧:

js
// pages.json:分包加载,把非核心页面移出主包
{
  "subPackages": [
    { "root": "pagesOrder", "pages": [{ "path": "list", "style": {} }] },
    { "root": "pagesMine",  "pages": [{ "path": "index", "style": {} }] }
  ],
  "preloadRule": {
    "pages/index/index": { "network": "all", "packages": ["pagesOrder"] }
  }
}
  1. 页面分包:只留首页、登录等核心页在主包,订单、个人中心、活动页全部移入分包;运行时才跳转的分包配 preloadRule 预下载兜底体验。
  2. 静态资源外置:大于 50KB 的图片上传 CDN 或云存储,代码里只留 URL;本地只保留首屏必需的小图。
  3. 图片格式与压缩:批量转 WebP(体积通常省 25%~50%),雪碧图换 CSS 或 SVG 图标;字体文件做子集化,只保留实际用到的字符。

检测方法:小程序端用开发者工具的"代码依赖分析"找出体积大头;HBuilderX 发行时勾选压缩与 Tree-Shaking(按项目配置,以官方文档为准),对比发行包前后大小。

渲染性能:setData 批量化与长列表虚拟化 ​

小程序架构下,JS 层与渲染层分离,数据要经通信桥同步,这是多数卡顿的根源。两个动作收益最大:

  1. setData 批量化:避免在循环或高频事件(滚动、输入)里逐条更新数据。错误示范与正确写法对比:
js
// 错误:滚动事件里高频单点更新,通信桥被打爆
onPageScroll(e) { this.scrollTop = e.scrollTop }

// 正确:合并更新 + 节流,把多次变更合并成一次传输
let ticking = false
onPageScroll(e) {
  if (ticking) return
  ticking = true
  setTimeout(() => {
    this.scrollTop = e.scrollTop // 一次批量提交
    ticking = false
  }, 100)
}
  1. 长列表虚拟化:超过 100 条的列表改为"可视区渲染"——只渲染屏幕内及上下各一屏的条目,配合定高条目或 uni-ui 的虚拟列表组件。检测方法:真机滚动列表,观察帧率曲线是否稳定在 50 帧以上,以及页面 WXML 节点数(经验参考:单页节点超 1000 个就该警惕)。

辅助手段还包括:图片设置 width/height 或懒加载避免布局抖动、骨架屏替代 loading 白屏、CSS 动画优先用 transform/opacity 避免触发重排。

把优化制度化 ​

单次优化救不了持续劣化,建议建立三条制度:合入前用工具跑一次体验评分,低于阈值不允许发布;真机性能数据接入监控(小程序后台体验评分每日报表、APP 端自建关键页面耗时上报);把"首屏时间、主包体积、列表帧率"三个数字写进版本发布检查单。以猫拽低代码(CatPull)为例,其可视化设计器产出的 DSL 编译到多端时,平台层统一处理了分包组织与数据绑定方式,页面结构由 Schema 约束,天然避免"单页塞几千个节点"的失控场景——用平台约束替代人工自律,是低代码路线在性能治理上的结构性优势。

FAQs ​

Q1:分包后首次进入分包页面变慢怎么办? ​

A:为高频跳转的分包配置 preloadRule 预下载(WiFi 或全网络下提前拉取),并把分包内的首屏图片外置 CDN。若仍慢,检查分包间是否被依赖倒灌导致主包虚增。

Q2:主包 2MB 上限快超了,最先删什么? ​

A:优先级排序:外置大图与字体(通常占大头)→ 移动低频页面到分包 → 清理未使用的组件库按需引入。用代码依赖分析工具确认每一项的实际占用再动手。

Q3:APP 端和小程序端优化策略一样吗? ​

A:主体相同(分包、资源、渲染),差异在两端:小程序重点管 setData 通信与包体积上限;APP 端额外关注原生层启动(splash、插件数量)与 webview 页面的渲染层级,原生插件越少启动越快。

延伸阅读 ​