微信小程序性能优化技巧
摘要: 如果小程序不够快,还要它干嘛?
Fundebug经授权转载,版权归原作者所有。
微信小程序如果想要优化性能,有关键性的两点:
- 提高加载性能
- 提高渲染性能
接下来分别来介绍一下:
提高加载性能
首先,问一个问题,当用户点击小程序后发生了什么?

上图中的三个状态,我们经常遇到,它们分别对应小程序的下面三个状态:
- 有三个点的白屏(左侧): 下载代码包的阶段
- 没有三个点的白屏(中间): 业务代码注入和渲染的阶段
- 加载中(右边): 业务代码中异步请求数据
总的来说,小程序呈现到用户面前,实际上经历了下面两个阶段:
- 运行环境的加载
- 下载代码包
下面具体介绍这两个阶段:
运行环境预加载
这步是微信做的。微信会在用户打开小程序之前就已经准备好环境,用户点击小程序入口后,直接下载小程序的代码包即可。
下载代码包启动小程序
小程序代码包里面的代码,不是小程序的源代码,而是编译、压缩、打包之后的代码包。
下图中,左侧的“预加载”对应的是运行环境的预加载,右侧的“小程序启动” 对应的是下载代码包启动小程序。

小程序提供的运行环境,分为逻辑层(AppService)和 视图层(webView),逻辑层是执行javascript的地方,视图层是渲染页面的地方。当小程序的代码包下载完毕后,业务代码分别注入逻辑层和渲染层。
提升加载性能的最最最关键性一点是,控制包的大小,这个也是微信官方的说法。
控制包的大小
提升体验最直接的方法是控制小程序包的大小,基本上可以说,1M的代码包,下载耗时1秒左右。
控制包的大小的措施
- 压缩代码,清理无用的代码
- 图片放在cdn
- 采用分包策略
- 分包预加载
- 独立分包(版本要求有点高)
除了上面讲的控制包的大小,对异步请求的优化也很重要。
对异步请求的优化
- onLoad 阶段就可以发起请求,不用等ready
- 请求结果放在缓存中, 下次接着用
- 请求中可以先展示骨架图
- 先反馈,再请求。比如说,点赞的按钮,可以先改变按钮的样式,再发起异步请求。
提升渲染性能
setData 干了啥
每调用一次setData, 都是逻辑层向渲染层的一次通讯,这个通信还不是直接传给webView, 而是通过走了native层,通讯的开销很大。
渲染层收到通讯后,还需要重新渲染出来,所以,emmm, 一次setData带来两次开销:通信的开销 + webview更新的开销。

在数据传输时,逻辑层会执行一次JSON.stringify来去除掉setData数据中不可传输的部分,之后将数据发送给视图层。同时,逻辑层还会将setData所设置的数据字段与data合并,使开发者可以用this.data读取到变更后的数据。
减少setData的数据量
如果一个数据不能会影响渲染层,则不用放在setData里面
合并setData的请求,减少通讯的次数
这个很好理解吧
列表的局部更新
在一个列表中,有n条数据,采用上拉加载更多的方式,假如这个时候想对其中某一个数据进行点赞操作,还能及时看到点赞的效果
此时,可以采用setData全局刷新,点赞完成之后,重新获取数据,再次进行全局重新渲染,这样做的优点是:方便,快捷!缺点是:用户体验极其不好,当用户刷量100多条数据后,重新渲染量大会出现空白期(没有渲染过来)
如果采用布局刷新,将点赞的id传过去,知道点的是那一条数据, 将点赞的id传过去,知道点的是那一条数据。
重新获取数据,查找相对应id的那条数据的下标(index是不会改变的),用setData进行局部刷新
this.setData({
list[index] = newList[index]
})
小心后台页面的js
小程序中可能有n个页面,所有的这些页面,虽然都拥有自己的webview(渲染层), 但是却共享同一个js运行环境。也就是说,当你跳到了另外一个页面(假设是B页面),本页面(假设是A页面)的定时器等js操作仍在进行,并且不会被销毁,并且会抢占B页面的资源。
在h5的环境中,当我们跳转到其他页面,老页面的js环境会被自动销毁,定时器什么都被销毁掉了,因此我们不需要关心老页面中,还有哪些js代码可能还会执行。但是在小程序中,我们必须手动的“清理”掉这样的代码。
小心onPageScroll
pageScroll 事件,也是一次通讯,是webview层向js逻辑层的通讯。这次通讯也是开销较大,如果考虑到这个事件被频繁的调用,回调函数如果有复杂的setData的话,emmmmm, 性能就会很差了。

小心获取节点位置
在h5 中的环境中,为了实现懒加载、下拉加载,我们不得不去获取节点的位置。
为啥说不得不,是因为我们本可以用新的api ——intersectionObject去轻松实现(google等主流浏览器都已经支持了),但是微信的内置X5浏览器很遗憾的不支持。
没想到,在小程序的环境中,微信竟然良心发现,支持intersectionObject api, 因此获取节点的信息,尽量还是用这api 吧。
尽可能使用小程序组件
自定义组件的更新只在组件内部进行,不受页面其他不能分内容的影响;比如一些运营活动的定时模块可以单独抽出来,做成一个定时组件,定时组件的更新并不会影响页面上其他元素的更新;各个组件也将具有各自独立的逻辑空间。每个组件都分别拥有自己的独立的数据、setData调用
优化心得
相比于上面的优化策略,最重要的是找出小程序中的性能瓶颈。在自己的优化实践中,遇到了下面的问题:
下拉加载更多,特别特别卡,通过列表局部更新的技巧,发现性能改善不大。 后来发现,是因为首页需要监听scroll事件,导致scroll事件被频繁的触发,回调函数中有耗时操作,导致onreachBottom事件被阻塞了,也就是说,要等大概1~2秒才会去发起下一页的请求。 取消掉scroll事件的监听,原本>4s的加载时间,控制在1s之内。
一些坑
- 在微信开发者工具没有办法复现某些性能问题,是因为从逻辑层到webview的通讯,开发者工具底层是通过onpostMessage, 微信ios好像是微信自己实现的桥接。所以强烈建议使用真机进行调试
- 微信开发者工具,没有办法在【network】里面看到图片资源的加载,通过【trace】面板连接安卓真机也没有办法看到。如果想测试懒加载的效果,就比较麻烦,需要通过设置微信开发者工具的代理到127.0.0.1,通过charles可以抓包看到(截止2018年11月1日是这样的)
一些迷茫
搞微信小程序遇到的这些坑,虽然可以收获满满的填坑经验,但是这些填坑经验并不算是真正的计算机知识,因为这些知识的并不是基于对本质底层的理解,而是依靠经验,而经验是很快就会过时,可能下一次小程序api来一次大的升级,小程序优化手段马上就会换成另外一种。
关于Fundebug
Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了7亿+错误事件,得到了Google、360、金山软件、百姓网等众多知名用户的认可。欢迎免费试用!

微信小程序性能优化技巧的更多相关文章
- 微信小程序性能优化之一
性能优化 界面和业务逻辑之间事件交互小程序调用nativeNative回调小程序 图片源文件优化 渲染优化 ---------------------------------------------- ...
- Java程序性能优化技巧
Java程序性能优化技巧 多线程.集合.网络编程.内存优化.缓冲..spring.设计模式.软件工程.编程思想 1.生成对象时,合理分配空间和大小new ArrayList(100); 2.优化for ...
- 微信小程序开发优化
一.开发优化一 1.使用Vant Weapp 1.1 什么是Vant Weapp Vant Weapp官网链接 Vant Weapp是有赞前端团队开源的一套小程序UI组件库,助力开发者快速搭建小程序应 ...
- 微信小程序性能测试之jmeter踩坑秘籍(前言)
最近要做个微信小程序的性能压测,虽然之前只做过web端的,但想一想都是压后端的接口,所以果断答应了下来,之前对jmeter都是小打小闹,所以趁着这次机会好好摆弄摆弄. ---------------- ...
- 【微信小程序推广营销】教你微信小程序SEO优化,让你的小程序快人一步抢占先机
今年一月份上线的小程序,经过近一年的沉淀发酵,现在也进入了快速发展期. 在未来肯定会有越来越多的小程序诞生,小程序多了就需要搜索,那么如何让自己的小程序在众多的小程序中脱颖而出,这就需要小程序SEO优 ...
- 微信小程序~性能
(1)优化建议 setData setData 是小程序开发中使用最频繁的接口,也是最容易引发性能问题的接口.在介绍常见的错误用法前,先简单介绍一下 setData 背后的工作原理. 工作原理 小程序 ...
- 微信小程序:优化页面要渲染的属性
问题:页面中只用到四个属性:goods_name,goods_price,goods_introduce,pics,但是整个对象中有22个属性,小程序中建议:data中只存放标签中要使用的数据,而现在 ...
- 微信小程序开发调试技巧
1. 查看线上小程序console a. 先打开开发小程序console b. 再打开线上小程序,此时可以查看console
- 微信小程序:优化接口代码-提取公共接口路径
方法一.将公共部分提取出来定义为baseURL变量 简化url,把里面公共部分提取出来.如https://api-hmugo-web.itheima.net/api/public/v1/categor ...
随机推荐
- 超实用的 Nginx 极简教程,覆盖了常用场景
概述 什么是 Nginx? Nginx (engine x) 是一款轻量级的 Web 服务器 .反向代理服务器及电子邮件(IMAP/POP3)代理服务器. 什么是反向代理? 反向代理(Reverse ...
- Javascript高级编程学习笔记(79)—— 表单(7)选择框脚本
选择框脚本 选择框由<option>和<select>元素创建,为了方便选择框的交互,除了提供表单字段的公有方法之外 HTMLSelectElement 类型还提供下列特有的属 ...
- 机器学习入门04 - 使用TensorFlow的起始步骤 (First Steps with TensorFlow)
原文链接:https://developers.google.com/machine-learning/crash-course/first-steps-with-tensorflow/ 1- 工具包 ...
- 1 分钟教会你用 Spring Boot 发邮件
Spring Boot 提供了一个发送邮件的简单抽象,使用的是下面这个接口. org.springframework.mail.javamail.JavaMailSender Spring Boot ...
- sql中base64解码、译码
1.5.6版本及之后的版本的base64 主要就是两个MySQL内部函数to_base64和from_base64,使用也很简单,如下: 1)先查看MySQL的版本:mysql> select ...
- jQuery源码——.html()方法原理解析
在将字符串转化为html碎片时,一般会将字符串作为容器的innerHTML属性赋值.但innerHTML有很多局限性,比如我们想转化的字符串中有<script>标签并且包含一个立即执行的函 ...
- mysql 开发进阶篇系列 52 权限与安全(系统四个权限表的粒度控制关系)
一.概述 接着上篇的权限介绍,当用户进行连接的时候,权限表的存取过程有以下两个阶段: (1) 先从user表中的host,user, authentication_string 这3个字段中判断连接的 ...
- async/await异步处理demo
async/await异步处理demo 下载地址: async/await异步处理demo
- JavaScript和Ajax部分(4)
31. 什么是jQuery选择器 1)jQuery选择器继承了CSS与Path语言的部分语法,允许通过标签名.属性名或内容对DOM元素进行快速.准确的选择,而不必担心浏览器的兼容性,通过jQuery选 ...
- 【SqlServer系列】远程访问
1 概述 已发布[SqlServer系列]文章如下: [SqlServer系列]SQLSERVER安装教程 [SqlServer系列]数据库三大范式 [SqlServer系列]表单查询 [SqlS ...