微信小程序项目性能优化法则

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情

业务背景

在开发小程序时所关注的前端性能,大多停留在首屏时间,也就是用户打开小程序到首屏加载完成的时长。通过微信的小程序的架构图可以得知,小程序采用安全高效的双线程模型,在启动时,也分为逻辑层的启动和视图层的启动,逻辑层的启动主要是加载 JS 代码,视图层则是启动 WebView 对页面进行加载和渲染。

小程序的性能优化难点主要在主包、更确切一点说是首页,首页包过大上,它导致逻辑层加载过慢,首屏时间超标。下面将对小程序的常见项目优化做一些实际的总结。

目前体验评分共有27条规则,共分为三类:性能、体验、最佳实践,满足规则要求得分(100分),否则不得分(0分),最后根据各规则权重和公式计算出总得分,详细的指标和权重见第三部分。

image.png

通过IDE的自测和官方miniTest工具的测试,目前我所负责的小程序还有很多的可提升空间,目前就以我开发的小程序为例,来介绍一下小程序在性能优化方面的经验。

1、从性能来看,目前均分在95分左右,仍然存在的扣分项为 “ 存在请求的耗时太长 ”,分别为引用的小程序框架中发起的请求和 WiFi 落地页获取页面路由发起的服务端请求,后期可推动两方进行优化

2、从体验来看,高星/低星落地页的体验均为100,完成度较高

3、从最佳实践来看,唯一的扣分点(10分)为服务下发了 http 的图片,服务端将于11.25修改上线,后期该评分项将不会扣分

根据我的自身经验,总结了以下小程序性能优化时的扣分点以及有效的改进措施:

扣分点 影响 有效措施
首屏时间过长1、小程序启动时间慢2、白屏时间长3、服务请求时间长、渲染数据依赖的计算复杂4、页面渲染慢 首屏时间太长会导致用户长时间看到的都是白屏,影响使用体验首屏时间不应超过 5 秒 1、减少代码包大小-  图片、音频、视频、字体等资源文件部署到 CDN
  •  使用 代码静态依赖分析 清除无用资源和依赖
  •  JS tree-shakingCSS tree-shaking 剔除无用函数、样式
  •  公共组件提取,代码复用,避免代码冗余2、使用骨架屏-  使用微信开发者工具 生成骨架屏 优化用户体验3、提前请求、请求拆分、请求缓存、复杂逻辑计算后移- 提前做异步数据请求,不需要等待页面渲染
  • 主接口拆分主体模块和非主体模块,非关键渲染的数据推迟请求,降低请求耗时,减少返回数据量
  • 对实时性要求不高的接口请求优先读取缓存,等接口返回后重新渲染,setStoragegetStorage
  • 避免进行 CPU 密集型的计算,复杂逻辑处理由服务端接口处理完直接返回渲染数据3、分屏渲染、减少节点数和 setData 调用次数-  使用渐进式渲染,根据优先级先渲染关键部分,不可见部分延迟更新
  •  优化代码结构,减少页面无意义的 wxml 个数,节点深度和子节点个数
  •  视图层渲染无关的数据用统一变量存储,不要放在 data 里
扣分点 影响 有效措施
图片问题1、代码包中包含过大的图片资源2、图片体积大,请求时间长3、图片请求数过多 1、大量图片资源会延长代码包下载耗时,影响小程序启动时间2、图片太大会增加下载时间和内存的消耗3、同时间图片请求数过多会触发小程序并行请求数量的限制,导致页面加载缓慢 1、减少代码包中的图片资源-  过大的图片不要放在代码包中,部署到 CDN2、图片压缩、动态切图、使用字体图标、选用合适的图片格式-  图片上传前压缩,tinypng 工具
  •  服务下发的过大图片裁剪降质,如 动态切图
  •  纯色图标使用 font-face,如 hotelplanning_icon
  •  图片使用 webp 格式,考虑到部分机型可能不兼容,根据设备类型渐进式使用3、小图合并、懒加载-  使用雪碧图避免请求多张图片,sprite 工具
  •  图片懒加载,lazy-load
扣分点 影响 有效措施
setData 使用不当1、频繁使用 setData2、setData 的数据量过大3、data 的某些变量在 wxml 没有依赖 1、频繁使用 setData 会造成 js 阻塞问题,性能消耗极大2、setData 传输的数据量越多,线程间通信的耗时越长,渲染速度就越慢3、多个页面共用一套 js,某个变量只在其中一个 wxml 中使用,会导致变量在另外的 wxml 中没有依赖扣分 1、setData 合并、pageScroll 事件-  避免单个函数多次 setData,应合并统一 setData
  •  非必要不监听 pageScroll,避免在 onPageScroll 的事件回调里 setData
  •  页面切入后台的  setData 推迟到页面展示时执行2、局部刷新、diff 算法筛选出需要更新的数据-  列表局部刷新:this.setData({[`list[${index}].show`]: true})
  •  数据 diff 减少 data 体积,筛选出有必要更新的数据再 setData3、未用于页面渲染的变量存储在固定对象中、hack 方法-  未用于页面渲染的变量不能放在 data 里
  •  多个页面复用 js 的情况使用 hack 避免 wxml 没有依赖扣分     
扣分点 影响 有效措施
瀑布流1、一个页面多个 video 组件,不应该超过3个2、同时请求多个图片资源 1、video 组件在 src 赋值就会渲染,多个 video 组件会导致部分视频模块黑屏2、太多图片请求会触发浏览器并行加载的限制,导致图片加载缓慢 1、使用 image 代替 video,播放时替换-  不需要当页播放,跳转播放的情况,使用 image 封面图 
  •  需要当页播放的情况,使用 image 列表,选中时将 image 替换成 video2、组件按需加载、微信的 recycle-view 组件-  不在视图内的组件先用等尺寸的骨架图占位,IntersectionObserver 监听列表内组件与视窗相交,距离小于临界点时,取缓存数据渲染组件
  •  使用微信的长列表组件,recycle-view
扣分点 影响 有效措施
异常问题1、避免 JS 异常2、避免网络异常 1、js 异常可能会导致业务逻辑中断2、请求失败可能导致程序的交互无法进行 1、js 异常修复、监控-  修复线上 js error
  •  异常业务场景 监控2、try-catch 异常捕获、异常监控-  try-catch 捕获网络异常,补充兜底逻辑增强代码鲁棒性
  •  使用埋点收集、监控和分析接口异常数据进行针对性优化
扣分点 影响 有效措施
可点击元素的响应区域过小 过小的响应热区会带来不好的交互体验 增大元素响应热区-  padding
  •  透明的 border
  •  box-shdow
扣分点 影响 有效措施
内存占用过高 小程序占用系统资源过高,就有可能会被系统销毁或被微信客户端主动回收 -  内存预警(wx.onMemoryWarning),监听、收集和分析告警,针对性地做优化

总结

  • 在保证功能的前提下尽量使用结构简单的 UI;

  • 尽量降低 JavaScript 逻辑的复杂度;

  • 尽量减少 setData 的调用频次和携带的数据体量。


欢迎各位前端大佬也补充一些微信小程序项目优化的细节,其他厂商的小程序也可以,共同成长

猜你喜欢

转载自juejin.im/post/7110230573100040228