- 微信小程序性能优化入门指南(转载)
原文地址:https://segmentfault.com/a/1190000016901634 小程序从发布到现在也已经有将近两年的时间,越来越来多的公司开始重视小程序生态带来的流量,今年也由于小程序平台对外能力的越来越多的开放以及小程序平台的自身优化,越来越多的开发者也自主的投入到小程序的开发当中,现在,作为前端如果会写小程序,绝对是一个不折不扣的面试加分项。 相信不少人刚接触小程序时的感觉大都是小程序很简单,开发只要是会写html、css、js就可以了,但是当自己的第一个小程序开发完成上线时,却发现小程序体验非常糟糕,接下来就让我们一窥小程序优化之道。 加载流程要想给小程序做优化,对小程序的加载流程一定要有一定的了解,小程序是怎么加载的,让我们先来看一个图片: [图片] 这三个图片大家一定都不陌生,当你打开一个小程序的时候就会经历这三个过程: 资源准备,这个过程就是小程序在下载你的代码包的过程业务代码注入和渲染,这个过程就是小程序将的业务代码分别注入视图层和逻辑层,并在视图层做视图的渲染异步数据的请求,显示加载中的时候,其实就是在到达首页时,如果首页有异步数据请求,这个时候小程序就会执行异步数据请求上述就是对小程序的启动过程的一个简单概述,让我们再来看一个更加具体一点的图片,可能会更好理解小程序启动过程: [图片] 从这个图片可以看到,小程序在启动加载的时候,其实分为两部分,一部分是逻辑层的启动启动,另一部分是视图层的启动,逻辑层的启动就是加载小程序的js代码,视图层的启动webview对页面进行加载和渲染,那预加载又是什么时候执行的呢?其实在微信动的时候,小程序平台就开始静默执行与加载的过程,包括JS引擎初始化和WebView的初始化,然后会注入小程序自带的公共库,例如自带api、组件等,后面的小程序启动,就是上面说过的打开一个小程序具体的启动加载过程了,下载代码包,分别注入逻辑层和视图层,然后共同完成首屏渲染。 启动性能优化讲完小程序的启动过程,就可以开始介绍具体的性能优化方案了,让我们一起看看影响小程序性能的因素以及具体的解决办法 代码包大小代码包大小会直接影响小程序的启动速度,代码包越大,小程序的启动时间就越长,在小程序启动时,下载代码包和代码注入的时间和小程序代码包大小是成正比的,一般小程序的平均启动时间是2s左右,可以看看你的小程序有没有拖后腿,那么如何控制包大小呢? 资源控制开启开发工具”上传代码时自动压缩”,小程序开发工具有一个上传代码时自动压缩的功能,当开启时,会在你上传代码时为你做代码压缩,除了这个,我们也可以通过使用第三方打包工具做代码压缩,如webpack、grunt、grulp。及时清理无用代码和资源文件,无用的代码和资源也会占用一定的包大小。减少代码包中的资源文件,将资源存放在cdn上,小程序开发工具对资源文件的压缩比率非常低,资源有条件的可以尽量放在CDN上,因为小程序开发工具对资源文件的压缩比率非常低,只有10%左右,或者也可以用第三编译工具对资源文件自己进行压缩处理分包加载[图片] 分包加载是小程序提高加载启动性能的一个重要方法,如果有人还不了解,可以点开链接看官方介绍,那么如何做好分包加载呢? 将小程序中不常用的代码放在分包中,主包内只保留用户最常访问的页面,但是由于官方规定tab页面只能放在主包中,因为小程序启动时只会加载主包,使用时按需下载分包,不会在加载时一次将整个代码包下载,这样就能有效减少启动加载的时间。 但是分包加载也有它的局限性,用户首次打开分包页面时,需要先进行分包代码的加载和注入,会造成页面切换时产生一定的延时,因此在此基础上,官方又推出了分包预加载和独立分包。 分包预加载先来看一下之前分包加载时的流程是怎样的: [图片] 那么分包预加载是怎么干的呢?分包预下载:提前配置可能会跳到哪些分包,框架在进入页面后根据配置进行预下载,分包预加载会在你进入主包页面后,为你静默开启分包代码的下载和注入,这个过程是无感的,来看一下分包预加载的流程是怎样的: [图片] 分包预加载需要注意的是:同一个分包中的页面享有共同的预下载大小限额2M,限额会在工具中打包时校验,因此不能把所有的分包页面都配置到分包预加载的配置中,只配置主包页面会跳转的页面即可。 独立分包独立分包又是什么呢?由于从分包页面启动是,必须要依赖于主包的下载和注入,启动速度会受到主包大小的制约,因此这就有了独立分包,独立分包在启动分包页面时,可以独立启动而不需要依赖主包,这样就可以减少主包下载和注入的时间,通常情况下我们会将活动、广告一类的具有独立逻辑的功能代码标记为一个独立分包,在分包页面启动时,可以不依赖于主包启动,只下载分包代码进行注入。让我们来看一下独立分包的加载流程是怎样的: [图片] 首屏加载性能优化首屏加载的体验对小程序来说十分重要,那么如何提升首屏加载性能呢? 提前请求:异步数据数据请求不需要等待页面渲染完成利用缓存:利用storage API对异步请求数据进行缓存,二次启动时先利用缓存数据渲染页面,再进行后台更新避免白屏:先展示页面骨架和基础内容及时反馈:及时地对需要用户等待的交互操作给出反馈,避免用户以为小程序没有响应渲染性能优化要想提高渲染性能,就需要知道小程序如何做页面渲染的,让我们先来看一个页面渲染的流程图: [图片] js引擎和native都可以过js的计算或者data修改来对Webview发起绘制操作,但是对开发者来说最重要的就是js引擎和Webview之间的通信,这通信过程是一个跨进程通信,是非常耗时的一个过程,我们要提高渲染的性能,也就是减少这个跨进程通信的时间,那么怎么去减少跨进程通信的时间呢? 避免不当使用setData使用data在方法间共享数据,会增加setData传输的数据量,同时会增加页面重绘的概率data仅包括与页面相关的数据使用setData传输大量数据,通讯耗时与数据量正相关,页面更新延迟可能造成更新开销增加仅传输页面中发生变化的数据,使用setData的特殊key实现局部更新后台页面进行setData抢占前台页面的资源页面切入后台后的setData调用,延迟到页面重新展示的时候执行总结来说就是在data中只定义与页面渲染相关的数据,其他与页面渲染无关的数据都定义成普通变量,在做setData操作时,尽量只传输页面渲染需要的数据,当页面切换时,将后台执行的setData操作销毁,等到页面重新展示的时候再执行。 避免不当使用onPageScroll只在必要的时候监听pageScroll事件避免在onPageScroll中执行复杂逻辑避免在onPageSroll中频繁调用setData避免频繁查询节点信息(SelectQuery),部分场景使用节点布局相交状态监听(IntersectionObserver)替代由于onPageSroll事件监听在处理js引擎和webview之间的通信时也是一个跨进程通信,因此在使用onPageScroll事件时,要注意以上的几点内容,来进行相关的优化 使用自定义事件在需要频繁更新的场景下,自定组件的更新只在组件内部更新,不受页面其他部分内容复杂性影响,这样也可以在一定程度优化渲染性能 总结这篇文章简单的介绍了微信小程序性能优化的一些方法,还有很多我没有介绍到方法就需要大家自己去探索总结了。希望大家看完这篇文章能对小程序性能优化有一定的认识,如果有错误或不严谨的地方,欢迎批评指正,如果喜欢,欢迎点赞收藏。
2021-09-23 - 微信小程序获取openID及unionID
公众号openID和小程序openID说明 为了识别用户,每个用户针对每个公众号或小程序等应用会产生一个安全的OpenID 在小程序中,openID是小程序的普通用户的一个唯一的标识,只针对当前的小程序有效同理在公众号中openID是公众号的普通用户的一个唯一的标识,只针对当前的公众号有效冷知识:公众号包含服务号和订阅号。我们常开发的是服务号 同一个微信用户在小程序和公众号上的openid是不同的 UnionID 机制说明 微信的unionid机制说明: 如果开发者拥有多个移动应用、网站应用、和公众帐号(包括小程序),可通过 UnionID 来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的 UnionID 是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。简而言之,unionid是用来说明多个应用下用户身份一致性的问题。相比较而言,由于在同一个应用下每个用户的openid是唯一的,因此openid也是也可以用来标记用户身份,但是仅限于在同一个应用中。对于不同的应用,每个用户的openid是不一样的,要想在不同应用间识别用户的唯一性只可以用unionid。下面来举一个例子来说明,例如: 小耿开发者账号下有公众号A和小程序B,对于访问公众号A和小程序B的用户小龙有openidA与openidB(openidA!=openidB),openidA在公众号A应用中是唯一的,可以说明小龙的身份;openidB在小程序B中是唯一的,也可以说明小龙的身份。假如,我们现在要确定公众号A的用户小龙与小程序B的用户小龙是否为同一个用户小龙,我们根据openid能确定吗?很显然,不可以。此时用户的unionid就可以解决这个问题,即unionid是用来确定不同应用下用户的唯一性。如何获取? 公众号获取openID 参考文档:(建议放到后端处理)https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html http://note.youdao.com/noteshare?id=c391f6f88ae92c485b95f386309079b2&sub=0A4A104759AE4D5992457DC02E9FC194 小程序获取openID 1、需要在微信小程序调用登录开放接口 wx.login() 获取用户登陆凭证code。 wx.login()接口说明: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html2、向服务器发送请求,并将code一起发送过去。 3、接下来,在服务端调用auth.code2Session接口 接口说明 :https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html4、接口返回openid UnionID获取途径 公众号获取unionID 可以直接通过 openID 获取到该用户 UnionID(建议放到后端处理) https://developers.weixin.qq.com/doc/offiaccount/User_Management/Get_users_basic_information_UnionID.html#UinonId 小程序获取unionID 微信官方给出的途径: 绑定了开发者帐号的小程序,可以通过以下途径获取 UnionID。 1、如果开发者帐号下存在同主体的公众号,并且该用户已经关注了该公众号。开发者可以直接通过 wx.login + code2Session 获取到该用户 UnionID,无须用户再次授权。(以前是调用接口 wx.getUserInfo,或通过button获取:<button type='primary' open-type="getUserInfo">授权登录</button>,从解密数据中获取 UnionID。2021年4月13日以后就不支持这种方法了。相关文档:https://developers.weixin.qq.com/community/develop/doc/000cacfa20ce88df04cb468bc52801)2、如果开发者帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用。开发者也可以直接通过 wx.login + code2Session 获取到该用户 UnionID ,无须用户再次授权。3、用户在小程序(暂不支持小游戏)中支付完成后,开发者可以直接通过getPaidUnionId接口获取该用户的 UnionID,无需用户授权。注意:本接口仅在用户支付完成后的5分钟内有效,请开发者妥善处理。4、小程序端调用云函数时,如果开发者帐号下存在同主体的公众号,并且该用户已经关注了该公众号,可在云函数中通过 cloud.getWXContext 获取 UnionID。5、小程序端调用云函数时,如果开发者帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用,也可在云函数中通过 cloud.getWXContext 获取 UnionID。 在项目中采取下列方法来获取unionid第一种方法举例: 通过wx.login获取用户的code,因为获取openid和unionid需要用code然后就是通过微信的auth.code2Session获取我们最终想要的微信小程序中调用wx.login()获取到code,将code传给后端由后端直接调用接口: https://api.weixin.qq.com/sns/jscode2session?appid=自己的appid&secret=密钥&js_code=${code}&grant_type=authorization_code 获取openid和unionid、session_key onLoad: function (options) { this.wxLogin() }, wxLogin () { wx.login({ success: (res) => { //用户的code let userCode = rest.code console.log('wx.login==>',res) // 该流程放到后端处理=== // https://api.weixin.qq.com 不是合法域名,正式环境无法访问 ============= wx.request({ // 自行补上自己的 APPID 和 SECRET url:`https://api.weixin.qq.com/sns/jscode2session?appid=自己的appid&secret=密钥&js_code=${userCode}&grant_type=authorization_code`, success: res => { // 获取到用户的 openid console.log("用户的openid:" + res.data.openid); console.log("用户的unionid:" + res.data.unionid); console.log("用户的session_key:" + res.session_key); } }); } }) } tips:获取unionid的话是需要微信开放平台绑定小程序的,不然是不可能获取到的 查找 APPID 和 SECRET 微信公众平台->开发->开发管理->开发设置 auth.code2Session 比较简单,大家可以自行查看 link 参考文章: openid: https://developers.weixin.qq.com/community/develop/article/doc/000c80906b4210625f3bde3775bc13 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html unionid: https://www.jianshu.com/p/46efa68d9033 https://www.jianshu.com/p/03810ae56c4f
2021-04-06