微信小程序性能优化

前言

最近搞的小程序上线后,时间变得充足起来了,于是查阅文档搞下小程序的性能优化。

思路

一般性能优化分为首屏启动性能和运行时渲染性能两大项,而要针对性的优化,那么首先得要了解启动过程和运行时模型(小程序、H5、app内嵌webview等同理),下面总结下原生小程序上的性能优化。

优化启动性能

小程序启动流程

一般启动分为冷启动和热启动

  • 冷启动:如果用户首次打开,或小程序销毁后被用户再次打开,此时小程序需要重新加载启动,即冷启动。
  • 热启动:如果用户已经打开过某小程序,然后在一定时间内再次打开该小程序,此时小程序并未被销毁,只是从后台状态进入前台状态,这个过程就是热启动

一般优化启动性能是指优化冷启动,下面主要讲冷启动的优化。先来一张启动流程图:

从图中看出启动过程一般分为三个阶段:

  1. 环境准备
  • 小程序运行进程及运行环境的准备
  • 代码包下载、校验及初始化
  • 视图层系统组件、webview容器及原生组件的初始化
  • 逻辑层js引擎初始化及域创建
  1. 代码注入
  • 框架(wx api、小程序基础组件库)及第三方基础代码的初始化(weUI、插件)
  • 开发者代码注入
  1. 首屏渲染
  • 逻辑层页面初始化,这个时间点是 initDataSendTime,会有Page.onLoad事件派发
  • 视图层时间点走到viewLayerReaderStartTime,会有 Page.onShow事件派发
  • 开发者代码从后端拉取数据,准备data数据(非必须)
  • 页面渲染
  • 视图层时间点走到viewLayerReaderEndTime,会有 Page.onReady 事件派发标志着首屏渲染完成

优化点

这一过程主要考虑减少首屏加载包的大小,以及尽量缩短首屏渲染完成时间

减少包大小

  • 启用分包加载、代码里使用分包预加载减少下载分包等待时间
  • 静态资源常规压缩、上传cdn,代码里通过url访问(上传后需要把项目里的文件删除,或者配置project.config.json文件的 packOptions.ignore 字段,以指明上传时需要忽略的文件
  • 小程序项目里删除无用的静态资源文件、页面、组件等(官方的工具miniprogram-slim停止维护了...,不大管用,手动删除吧)

缩短首屏渲染完成(白屏)时间

App.onLuanch -> App.onShow -> Page.onReady事件标志首屏渲染完成。

  • 启用按需注入后,小程序仅注入当前访问页面所需的自定义组件和页面代码。未访问的页面、当前页面未声明的自定义组件不会被加载和初始化,对应代码文件将不被执行。
  • 在开启「按需注入」特性的前提下,「用时注入」可以指定一部分自定义组件不在小程序启动时注入,而是在真正渲染的时候才进行注入。
  • 在 App.onLuanch、App.onShow 事件里,避免耗时大的、同步的类 wx.xxxsync 接口调用(用异步的接口)
  • 配置数据预拉取和周期性更新机制,在page.onLoad里判断应用数据,加快页面内容显示
  • 使用数据缓存能力缓存接口数据
  • 对于低端机首次渲染需要较长时间的情况下,启用初始渲染缓存(二次打开生效)
  • 首页 生成骨架屏,在接口数据还没到来时,显示页面框架,减少用户焦虑

优化运行时渲染性能

先了解下小程序原理、重渲染机制

小程序原理

基于webview渲染的小程序架构使用逻辑层 AppService 和渲染层 WebView 的双线程模型,appservice线程负责js的执行,处理逻辑与数据,webview线程负责页面的渲染(wxml/wxss/wxs),native在两层之间提供数据传输和事件系统,如下:

重渲染机制

当每次调用setData更新数据时,都会和旧数据合并,并生成新节点树,然后使用新节点树有目标地将原节点树上需要更新的节点一一更新掉,这个过程就是重渲染(类比vdom diff),如下:

另外setData数据从逻辑层传到视图层所需时间与数据量的关系如下:

优化点

基于上面小程序原理知识及通用优化手段,有以下建议:

  • 减少wxml节点已层级(官方建议页面节点数少于1000,层数少于30,每个节点下的子节点数少于60)
  • 跟渲染无关的数据不要放到data里
  • 尽量合并setData的调用(promise.all)、尽量减少每次setData设时的数据量(如只更新大列表中的某一项的某个属性时可以用计算属性更新,如下:)
js 复制代码
// ...
const listData = this.data.listData;
this.setData({
  [listData[index].title]: '要更新啦',
  [listData[index].like]: true,
  // ...
})
// ...
  • 频繁触发的事件使用WXS脚本,在视图层完成事件处理
  • 使用 worker 与 WXWebAssembly 执行耗时任务
  • 对于长列表渲染、瀑布流布局等,可以切换成skyline渲染引擎,利用其提供的组件实现

工具

另外微信开发者工具上还有一些工具可以协助我们进行性能优化

  • performance(同web)
  • memory(同web)
  • audits 体验评分:定位和识别小程序运行过程中的体验问题,从性能、体验、最佳实践三个维度对小程序进行分析,同时提供优化建议
  • 代码质量 面板:通过静态代码检查发现问题并给出建议

评估优化

怎么评估优化效果(PPT数据展示~)呢,微信提供了几种查看性能数据的方法,建议使用 wx.getPerformance 接口直接获取当前小程序性能相关的信息,包括无法在 JS 代码中直接打点获取的一些时间信息,主要指标如下:

参考

相关推荐
YBN娜5 分钟前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=5 分钟前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
minDuck10 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!30 分钟前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。36 分钟前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
花花鱼42 分钟前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript
EricWang13581 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
September_ning1 小时前
React.lazy() 懒加载
前端·react.js·前端框架
web行路人1 小时前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架