一、小程序启动耗时
1) 用户首次访问或小程序同步更新时,命中环境预加载 2) 用户非首次访问,命中环境预加载 3) 用户非首次访问,未命中环境预加载
1、环境预加载
编辑切换为居中
添加图片注释,不超过 140 字(可选)
2、用户首次访问或小程序同步更新时,命中环境预加载启动流程
编辑切换为居中
添加图片注释,不超过 140 字(可选)
1) 资源准备
- 信息获取: 小程序的头像、昵称、版本、配置、权限等基本信息(同步请求、异步请求)
- 运行环境准备: 包括小程序进程、客户端原生部分的系统组件和 UI 元素(如 导航栏、tabBar 等)、渲染页面使用的 WebView 容器、开发者 JavaScript 代码的运行环境、小程序基础库, 由微信客户端控制,开发者目前无法直接进行优化
- 代码包准备: 从微信后台获取代码包地址,从 CDN 下载小程序代码包,并对代码包进行校验(同步下载、异步下载)
2) 小程序代码注入(逻辑层)
按顺序将小程序的配置和代码、插件或扩展库、开发者代码注入到 JavaScript 引擎中
3) 小程序代码注入(视图层)
WXSS 和 WXML 会编译成 JavaScript 代码注入到视图层
4) 首页(初次)渲染
在逻辑层小程序代码注入完成后,小程序框架会根据用户访问的页面,进行页面组件树初始化,生成初始数据发送到视图层
5) 首屏内容展示
如果首页的主体内容依赖网络请求(例如 wx.request)等异步来源、需要等待网络请求异步返回后,调用 setData 进行页面更新,才能呈现真正的页面 详情 小程序启动流程介绍 | 微信开放文档
代码中做统计上报, 可以依赖于getPerformance接口, 即采用appLaunch耗时, 包括代码包下载、js代码注入/执行、首页绘制、首页渲染等时间, 计算方式:
1) 起点为用户点击小程序图标,或小程序被拉起的时间;
2) 终点为首个页面 firstRender 结束时间。
3、官方建议标准
安卓 | ios | |
---|---|---|
需要下载或更新时 | 3.7s | 1.8s |
使用本地代码包时 | 2.6s | 0.9s |
4、性能制约因素
- 平台: 不同平台下(安卓、iOS、PC 等)设备性能、操作系统、框架实现、优化方案存在较大差异,启动耗时也存在较大的差异。
- 下载比例: 代码包下载和更新都会显著影响小程序启动耗时,在其他流程耗时稳定的情况下,下载比例升高会影响大盘启动耗时。
- 入口页面:不同页面启动时,根据所在分包的不同,需要下载的代码包数量和大小和代码注入量都存在差异。不同页面渲染耗时也存在差异。
- 机型分布:启动耗时和设备性能有较强关联,不同小程序或使用场景用户群体的差异可能导致机型分布的差异,进而影响大盘启动耗时。
- 网络环境:网络环境主要影响网络请求的耗时,如小程序信息获取、代码包下载等。
- 场景/访问来源:不同场景下,用户访问的页面不同,新用户比例也有差异,对启动耗时会有一定影响。
- 首次访问用户比例:用户首次访问小程序时,需要完整的进行小程序信息准备、代码包下载的流程,代码缓存也需要重新生成,启动耗时会比非首次访问高。
- 小程序版本更新:小程序版本更新时,用户需要更新小程序信息和代码包,代码缓存也需要重新生成,启动耗时会出现上涨
- 页面复杂度: 页面的逻辑复杂程度、组件数量、结构复杂度等都会影响
5、为什么安卓和 iOS 的启动耗时差异那么大?
- 两个平台的设备性能、系统功能和启动流程实现存在一定差异:
- iOS 设备的平均性能要好于安卓;
- iOS 小程序和微信共用进程,而 Android 上小程序运行在独立进程,需要额外的进程创建和一些基础模块的初始化流程;
- iOS 上需要使用系统提供的 WebView 和 JavaScript Core,初始化开销几乎可以忽略;
- 安卓 UI 和系统组件的创建的开销远高于 iOS。
二、页面切换耗时
编辑切换为居中
添加图片注释,不超过 140 字(可选)
1、加载分包(若有)
页面切换时需要下载分包,并在逻辑层注入执行分包内的 JS 代码
2、视图层页面初始化
每个页面都是由独立的 WebView 渲染的,因此页面切换时需要一个新的 WebView 环境
3、逻辑层页面初始化
完成分包加载和 WebView 创建后,客户端会向基础库派发路由事件, 基础库收到事件后会进行逻辑层的页面初始化
4、目标页面渲染
页面切换的目标页面不存在时,会触发页面的首次渲染 代码中做统计上报, 可以依赖于getPerformance接口统计数据, 即采用route耗时, 影响用户操作的连贯性和流畅度,是小程序运行时性能的一个重要组成部分, 包括分包加载、路由事件、页面渲染等时间, 计算方式:
1) 起点为触发页面切换;
2) 终点为页面切换动画完成;
详情页面切换优化 | 微信开放文档
三、JS代码注入时间
代码中自己未做统计上报, 可以依赖于getPerformance接口统计数据, 即采用evaluateScript耗时, 逻辑层 JS 代码注入(含编译和执行)耗时
四、页面渲染时间
直观感受, 用户能完全看到首屏内容的加载时间
可以采用小程序原生页面首次渲染耗时计算, 依赖于getPerformance接口统计数据, 即采用performance.firstRender, 因为这个统计是在页面内容完整呈现且某时间段内不再改变才触发的, 所以如果页面做了本地数据缓存, 此数据不一定就是用户首次看到页面的时间
1、性能制约因素
- 首屏业务复杂度、渲染dom层级处理、图片数量及大小、模块监听事件、原生组件性能、页面预加载等
- 手机性能
- 网络环境
- 打开方式(九宫格、菜单列表等)
- 缓存情况
- 版本发布
详情渲染性能优化 | 微信开放文档、资源加载优化 | 微信开放文档
不建议采用如下统计方式:
代码里自己计算, 首页配置获取完成时刻 - 首页组件onShow时刻, 误差比较大, 分析原因如下:
- 统计时刻不包括app的加载、中间件生命周期的处理等时间
- js单线程执行任务, 而项目里有太多的同步和异步任务, 对于异步任务执行时序不可控, 因此代码里采用前后时刻差计算的时间不准确
- 即使2是准确的, 在刚获取到首页配置后, 并不能完全确定所获取的配置已经在页面中渲染完成
建议采用如下统计方式:
使用小程序自带的页面首次渲染耗时统计, 起点为逻辑层收到路由事件, 终点为页面 onReady其时间包括:
- 页面和组件的代码注入的时间(因为页面和组件的代码注入过程成为了首次渲染过程的一部分, 脚本耗时降低,渲染时间提高属于正常现象)
- 渲染层代码注入完成时间
- 首次渲染参数在渲染层收到的时间
- 渲染层执行渲染开始时间
- 渲染层执行渲染结束时间
五、网络测速
通过发送一个空请求, 来测算当前网络环境下的响应时长. 非websocket的请求, 整个请求链路为 DNS -> TCP Connect -> SSL -> request -> response; 可以借助于小程序原生request调试信息计算, 可以在app.onLaunch首次建立请求的时候进行计算, 因为后续请求由于存在链路复用的情况, 在页面级的测速会存在耗时较低的情况
1、性能制约因素
- 网络环境
- 前后台切换
- HTTP2
不建议统计方式:
代码里自己计算, 请求结束时刻 - 请求开始时刻, 有一定误差, 分析原因如下:
- 测速函数的调用属于异步调用, 虽然起始时刻一般比较准确, 但是在请求等待时间内, js会去处理其他异步或同步任务, 导致结束时刻不准确
- 即使1是准确的, 这种统计并不能纯粹的反应请求的真实耗时, 只是一个粗略的计算
建议统计方式:
使用小程序request自带的请求profile信息, 用 响应接受完成时刻 - DNS域名查询开始时刻, 其时间包括:
- DNS 域名查询的时间
- HTTP(TCP) 连接建立的时间
- SSL连接建立的时间
- HTTP 响应全部接收完成的时间
详情网络调优 | 微信开放文档