小程序性能优化

news/2024/11/29 13:33:36/

目录

代码包体积优化

1.合理使用分包加载

1.1独立分包

1.2分包预下载

1.3分包异步化

2.避免非必要的全局自定义组件和插件

3.控制代码包内的资源文件

4.及时清理无用代码和资源

代码注入优化

1.启动过程中减少同步API调用

2.启动过程中避免CPU密集型任务

首屏渲染优化

1.使用 按需注入 和 用时注入

2.启用 初始渲染缓存

3. 避免引用未使用的自定义组件

4.精简首屏数据

5.提前首屏数据请求

6.缓存请求数据

7.骨架屏

发版频率控制

小程序运行时优化

1.合理使用setData

1.1 data 只应包含渲染相关的数据

1.2 控制 setData 的频率

1.3 控制 setData 合适的范围

1.4 setData只传递变化的部分

1.5 阻止后台页面setData

渲染性能优化

1. 适当监听页面或组件的scroll事件

2.选择高性能的动画实现方式

3.使用 intersectionObserver 监听元素曝光

4.控制WXML节点数量和层级

5.控制在page构造时传入的自定义数据量

页面切换优化

1.避免在 onHide/onUnload 中执行CPU密集型任务

2.首屏渲染优化

3.提前发起数据请求

4.控制预加载下个页面的时机

资源加载优化

1.控制图片资源大小

2.避免滥用image组件的widthFix/heightFix 模式

内存优化

1.定期处理内存告警问题

2.处理内存泄漏操作


代码包体积优化

1.合理使用分包加载

1.1独立分包

小程序中的某些场景(广告页、活动页、支付页等),通常功能不是很复杂且相对独立,同时对启动性能有很高的要求。

独立分包可以独立于主包合其他分包运行。从独立分包页面进入小程序时,不需要下载主包。

因此将要求高性能的页面放到独立分包中,优化启动速度,提高用户体验。

1.2分包预下载

1.3分包异步化

可以将小程序的分包从页面粒度细化到组件甚至文件粒度。这使得本来只能放在主包页面的部分插件、组件和代码逻辑可以剥离到分包中,并在运行时异步加载,从而进一步降低启动时所需要的包大小和代码量。

  • 组件异步化核心是通过异步加载分包模块的组件同时配合占位组件,来实现组件异步加载完成后进行替换。
  • js逻辑异步化的核心在于使用require方法进行注册。

分包异步化能有效解决主包大小过度膨胀的问题。

2.避免非必要的全局自定义组件和插件

在app.json中通过usingComponents 全局引用的自定义组件和通过 plugins 全局引入的插件,会在小程序启动时随主包一起下载和注入js代码,影响启动耗时。

3.控制代码包内的资源文件

小程序代码包在下载时,会使用ZSTD算法进行压缩,图片、音视频、字体等资源文件会占用较多代码包体积,并且通常难以进一步压缩,对于下载耗时的影响比代码文件打大得多。

静态资源尽量部署到CDN中,并使用URL进行引入(除非要做离线展示)

4.及时清理无用代码和资源

除了工具默认忽略或开发者明确声明忽略的文件,小程序打包回将工程目录下所有文件都打入代码包中。

不定期的分析代码包的文件构成和依赖关系,以此优化代码包大小和内容。或使用webpack、rollup等打包工具,对小程序代码进行预处理,可以利用tree-shaking等特性去除冗余代码,也要注意防止打包时引入不需要的库和依赖。

代码注入优化

1.启动过程中减少同步API调用

在小程序启动过程中,会注入开发者代码并顺序同步执行:App.onlaunchApp.onShowPage.onLoadPage.onShow

在小程序初始化代码和上述启动相关的几个声明周期中,应尽量减少或不调用同步API。绝大多数同步API会以 Sync 结尾,但有部分特例,比如 getSystemInfo (带不带sync都是同步的)

同步API虽然使用简单,但是会阻塞js现成,影响代码执行。

常见的有:

  -- getSystemInfo / getSystemInfoSync

  • 由于历史原因,这两个都是同步的API,同时这两个接口承载过多内容,单次调用耗时会比较长,不建议首屏调用,并且应该在调用后设置缓存,避免重复调用。

  -- getStorageSync / setStorageSync

  • 启动过程中多次续写也会显著影响小程序注入耗时
  • 简单数据共享不建议使用,建议使用 globalData 完成

2.启动过程中避免CPU密集型任务

在小程序初始化代码和启动相关的几个生命周期中,应避免执行复杂的运算逻辑。复杂运算也会阻塞当前js线程,影响启动耗时。建议将复杂的运算延时到启动完成后进行。 

首屏渲染优化

1.使用 按需注入 和 用时注入

2.启用 初始渲染缓存

3. 避免引用未使用的自定义组件

4.精简首屏数据

对于复杂页面可以采用 渐进式渲染 优先展示页面关键内容,对于非关键内容或者不可见部分延迟更新。

同时,与视图渲染无关的数据尽量不要放在 data 中,避免影响页面渲染时间。

5.提前首屏数据请求

小程序提供了如下能力:

数据预拉取

  • 预拉取能够在小程序冷启动时通过微信后台提前向第三方服务器拉取业务数据,当代码包加载完时可以更快的渲染页面,减少用户等待时间,从而提升小程序的打开速度
  • 需要在后台进行配置

周期性更新

  • 周期性更新能够在用户未打开小程序的情况下,也能从服务器提前拉取数据,当用户打开小程序时可以更快的渲染页面,减少用户等待时间,增强在弱网条件下的可用性
  • 同样需要在后台进行配置

6.缓存请求数据

7.骨架屏

发版频率控制

合理的规划版本发布,可以让微信拉取小程序信息更快,因为微信首次拉取小程序信息需要进行版本控制以及监控版本更新。

同时频繁的版本发布会让用户频繁的进行更新,用户会经常体验“首次加载”

小程序运行时优化

1.合理使用setData

setData 是小程序最容易造成性能问题的接口,尽管在使用 uniapp 的情况下,本质上组件更新最终还是会依赖 setData

1.1 data 只应包含渲染相关的数据

  • 渲染无关的数据直接丢到实例的this上
  • 避免使用data在页面或者组件间进行数据共享
  • 渲染间接相关的字段应该设置为纯数据字段(纯数据字段不会参与页面渲染,也就不会和UI线程通信,节约时间),然后通过 observers 控制逻辑更新,但是不能滥用,非data的数据禁止使用

1.2 控制 setData 的频率

  • 每次 setData 都会触发逻辑层虚拟DOM树的遍历和更新,也可能导致触发一次完整的页面渲染流程
  • 过于频繁(遍历过程中setData)会导致对端始终处于繁忙状态,UI交互无法完成,导致用户明显感觉页面卡顿

1.3 控制 setData 合适的范围

  • setData 只会引起 当前组件 和 当前组件的子组件 更新,因此频繁更新(秒杀倒计时等)的区域应抽离为单组件
  • 必要时增加 css contain减少重绘次数和回流范围(layout将回流限制在一定范围内)

1.4 setData只传递变化的部分

  • 如果将整个data传入setData,会增加页面更新开销和数据通信耗时,导致页面卡顿

1.5 阻止后台页面setData

  • 小程序挂在后台的页面数据是处于激活状态的,并且小程序的逻辑线程和UI线程都是共享的同一个线程,因此后台的逻辑更新和UI更新,也会影响前台的卡顿
  • 所有的更新逻辑应控制在页面 onHide 时暂停,在 onShow 后继续
  • 避免后台高频操作,比如定时器

渲染性能优化

1. 适当监听页面或组件的scroll事件

只要用户在 page 构造是传入了 onPageScroll 监听,基础库就会认为开发者需要监听页面scroll事件。此时,事件会以很高的频率从视图层发送到逻辑层,存在一定的通信开销。

使用时需要注意:

  • 非必要不监听scroll
  • 不要保留空的 onPageScroll 函数
  • 实现与滚动相关动画时,优先考虑 滚动驱动动画 或 wxs响应事件
  • 避免滚动事件中频繁调用setData或同步API
  • 避免滚动事件中执行CPU密集型任务

2.选择高性能的动画实现方式

  • 优先使用css渐变、css动画或小程序提供的动画实现方式
  • 避免使用setData实现动画,因为这样会导致频繁调用,极易出现卡顿。如果不得不使用,应改为组件级setData

3.使用 intersectionObserver 监听元素曝光

4.控制WXML节点数量和层级

5.控制在page构造时传入的自定义数据量

页面切换优化

1.避免在 onHide/onUnload 中执行CPU密集型任务

2.首屏渲染优化

3.提前发起数据请求

跳转页面时,可以提前发起请求,对下一个页面做一些准备,使用 eventChannel 将数据传输给下一页。

4.控制预加载下个页面的时机

小程序页面加载完成后,会预加载下一个页面。默认情况下,小程序框架会在当前页面 onReady 触发 200ms 后触发预加载。

在安卓上由于渲染线程中的webview共用同一个线程,因此在预加载下一个页面时会阻塞当前页面setData的执行,造成当前页面和用户交互产生延迟,影响用户看到页面完成内容的时机。

handleWebviewPreload 有如下取值:

  • static:页面onready后200ms触发预加载
  • auto:线程空闲时触发预加载(通过requestAnimateFrame执行判断是否空闲)
  • manual:手动预加载,在调用 wx.preloadWebview() 后执行下一页面预加载

注意:handleWebviewPreload仅支持安卓,低版本配置不生效。

资源加载优化

1.控制图片资源大小

2.避免滥用image组件的widthFix/heightFix 模式

会在图片加载完成后改变图片的尺寸,会引起页面大规模重排,造成抖动。 

内存优化

1.定期处理内存告警问题

2.处理内存泄漏操作


http://www.ppmy.cn/news/535950.html

相关文章

使用Event bus实现兄弟组件通讯

69. 使用Event bus实现兄弟组件通讯 1. 创建一个event bus实例 在Vue项目中,可以在src目录下新建一个event-bus.js文件,用来创建一个空的Vue实例,并导出该实例: import Vue from vue;export const EventBus new Vue();2. 在发…

(四)WPF - 布局

一、布局过程 WPF 布局包括两个阶段:一个测量阶段和排列阶段 在测量阶段,容器遍历所有子元素,并询问子元素它们所期望的尺寸。在排列阶段,容器在合适的位置放置子元素。(每个元素都被其父元素告知它自己的尺寸是多少…

surface pro7 问题集锦

Surface pro 7遇到的问题集锦 问题一:想入手surface pro7但是256G的比128G的要贵一千大洋,怎么办呢?预算有限,查到可以插TF卡拓容,于是就全网开始搜选卡攻略。终于找到你~ 上链接:https://post…

hwc2 surfaceflinger启动流程分析

先还是大体的来看下流程图,这个比hwc1复杂了好多,不是太好理解: 1.SurfaceFlinger.init "Starting with vr flinger active is not currently supported.");mRealHwc new HWComposer(false);mHwc mRealHwc;mHwc->setEventHa…

Platinum Maestro运动控制器 —— PVT模式笔记

文章目录 0. 文章说明1. PVT说明2.PVT 插值模式2.1 三次多项式插值(eCUBIC_POLYNOM)2.2 五次多项式插值(eQUINTIC_ON_CUBIC)2.3 七次样条多项式(eSEPTIC_ON_CUBIC)2.4 正弦插值2.4.1 三角正弦插值(eCYCLOID_VELOCITY_MODIFIED1)2.4.2 梯形正弦插值(eCYCLOID_VELOCITY_MODIFIED2…

SurfaceFlinger模块

SurfaceFlinger是一个系统服务,作用就是接受不同layer的buffer数据进行合成,然后发送到显示设备进行显示。 SurfaceFlinger进程是什么时候起来的? 在之前的Android低版本手机上,SurfaceFlinger进程是在init.rc中启动的&#xff0…

androidP Surface到SurfaceFlinger -->创建Surface (一)

创建Surface 前言ViewRootImpl创建Surface 前言 我们前面已经分析过Activity启动如何去连接到SurfaceFlinger了,接下来就看Activity的Surface的创建到SurfaceFlinger的过程。ViewRootImpl创建Surface 在调用了WindowManagerGlobal的addView方法之后会首先去创建一个…

Ansys Speos | 基于 Workbench 和 Speos 的准直全反射透镜优化设计案例

概述 基于Ansys Speos软件,可以准确建立光学系统模型并进行成像效果仿真。在使用Speos进行光学系统设计过程中,当完成初始光学系统建模后,还需要进一步结合仿真结果,调整出满足设计要求的系统参数,如果采用手动调整参…