前言
大师好,我是HoMeTown,比来要做一个小法式的项目,项目启动之前,回首自己之前做过的小法式,感受做的还是不够好,比来进修了一下小法式优化计划,这块总结一份小我笔记,以便参考,同时分享给大师,共勉。
关于微信小法式
微信小法式上线至今已经大约已经有5年的时候,5年的时候,小法式的开辟才能经过微信团队的不竭尽力优化,已经日益完善,不再像之前一样,翻翻文档就能完成一个简易的项目了,出格是性能优化方面,会优化与不会优化更是对产物的结果有着决议性的影响。
哪些部分需要优化?
- 首页白屏现象
- Loading加载时候太长,页面很久不显现
- 点击页面链接,页面跳转迟钝
- 按钮单击无响应
- 长内容列表,内容越多,越卡顿
- ......
有了优化的偏向,便可以按照题目逐一诊断了
小法式的启动流程?
运转载体
- iOS、Mac
- Android、PC
- 微信开辟者工具
情况预备
- 小法式运转进程及运转情况预备
- 代码包下载、校验及初始化
- 视图层系统组件、WebView容器和原生组件的初始化
- 原生组件的初始化
- 逻辑层JS引擎初始化及域建立
代码注入
- 框架及第三方根本代码的初始化
- 小法式根本库注入
- 扩大库注入
- 插件、自界说组件注入
- 开辟者代码注入
- 逻辑层代码「这里会派发App.onLaunch还有App.onShow这些事务」
- 视图层代码
首屏衬着
- 逻辑层页面初始化,这个时候点是initDataSendTime,会派发Page.onLoad事务
- 视图层时候点走到viewLayerReaderStartTime,会派发Page.onShow事务
- 开辟者代码从后端拉取,预备data数据
- 页面衬着
- 视图层时候点走到viewLayerReaderEndTime,会派发Page.onReady事务,意味着首屏衬着完成
启动方式
冷启动
小法式在用户设惫亓一次翻开大概是烧毁以后再翻开,大概是30分钟今后
热启动
热启动是相对于冷启动而言的,热启动是小法式启动的一种优化机制,小法式进入背景30分钟之内再次进到前台,可以间接从背景状态然后答复到前台,所以,在这类情况下,刚刚阿谁代码注入、首屏衬着等根本工作就不会再履行了,设备App.onLaunch、Page.onLoad等这些一次性的生命周期,也不会有了。
结论 由此,可以得出,要做小法式的性能优化,主如果做冷启动这块的优化以及运转时衬着性能的一个优化,小法式冷启动流程里触及到一些法式和生命周期。
生命周期
在小法式中App和Page都有他们各自的生命周期函数。
App
- onLaunch,监听小法式初始化的事务
- onShow 监听小法式启动或切前台的事务
- onHide 监听小法式切背景的时候
Page
- onLoad 监听页面加载
- onShow 监听页面显现
- onReady 监听页面初度衬着完成
- onHide 监听页面隐藏
- onUnload 监听页面卸载
优化技能
利用骨架屏
骨架屏的目标是为了减缓用户期待的情感
利用
如图,在小法式开辟者工具中,点击这里,天生骨架屏代码
然后他会天生两个文件:index.skeleton.wxml & index.skeleton.wxss
别离在index.wxml & index.wxss引入
总结
- 在data数据工具中默许设备loading即是true。
- 不要间接点窜天生的骨架屏的一个代码。经过设置去点窜。
- **不要过度去利用骨架屏。一般只给主页去增加骨架屏结果 **
优化长列表
优化长列表,利用recycle-view & recycle-item 虚拟DOM组件,在衬着的时辰需要晓得每个循环单元的一个高度,这是消耗代码需要传递给组件的,在recycle-view组件里面,用户滑动的是数据而不是组件自己。
利用 首先初始化package.json- // npm初始化package.json文件
- npm init -y
复制代码 安装- // 安装 miniprogram-recycle-view插件
- npm install --save miniprogram-recycle-view
复制代码 构建依靠
天生miniprogram_npm目录
组件内援用
代码中利用
list.wxml- <recycle-view batch=&#34;{{batchSetRecycleData}}&#34; id=&#34;recycleId&#34; catchscroll=&#34;onScroll&#34;>
- <view slot=&#34;before&#34;>长列表前面的内容</view>
- <recycle-item wx:for=&#34;{{recycleList}}&#34; wx:key=&#34;id&#34;>
- <view>
- <image style=&#39;width:80px;height:80px;float:left;&#39; src=&#34;{{item.image_url}}&#34;></image>
- {{item.idx+1}}. {{item.title}}
- </view>
- </recycle-item>
- <view slot=&#34;after&#34;>长列表前面的内容</view>
- </recycle-view>
复制代码 list.js- const createRecycleContext = require(&#39;miniprogram-recycle-view&#39;)
- Page({
- onReady: function () {
- var ctx = createRecycleContext({
- id: &#39;recycleId&#39;,
- dataKey: &#39;recycleList&#39;,
- page: this,
- itemSize: this.itemSizeFunc
- })
- ctx.append([{
- image_url: &#39;https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/09883c4389f642829c96b6216eebea85~tplv-k3u1fbpfcp-watermark.image?&#39;,
- idx: 1,
- title: &#39;你好&#39;
- }])
- // ctx.update(beginIndex, list)
- // ctx.destroy()
- },
- onScroll() {
- console.log(&#39;scroll&#39;)
- },
- itemSizeFunc: function (item, idx) {
- console.log(item)
- return {
- width: 375,
- height: 100
- }
- }
- })
复制代码 总结
代码写起来不是那末舒服,组件利用不友爱,可是对性能确切还不错。
利用页面庞器
偶然辰我们在页面上会弹出一些特定的半屏窗口,例如登录窗口。这时辰假如用户在iOS装备上利用了左滑手势大概是在Android设惫亓击了物理返回键,会形成页面跳转到上一个页面,这在大大都情况下它并不是用户的实在本意,用户能够只是想将当前弹出的半屏的假页面给它关掉。
page-container页面庞器,是不需要引入即可以利用。
利用- <page-container :show=&#34;{{show}}&#34;>
- ...
- </page-container>
复制代码 总结
这个组件实在就是避免用户的左滑大概按键返回误操纵,致使全部页面回退的题目。
优化动画结果
实现动画的方式:
- 是利用Animation工具,实现CSS动画
- 利用页面或组件工具,具有的animate方式实现的关键帧动画
- 利用转动事务驱动的响应式动画
- 经过WXS剧本,实现了一个款式动画
- 经过第三方库实现animate.css
代码按需注入
代码懒加载
利用- // app.json
- &#34;lazyCodeLoading&#34;: &#34;requiredComponents&#34;
复制代码 出现以下提醒,代表成功
静态初始化衬着缓存
第一次页面运转时,由微信客户端负责将页面在当地的某个地区缓存起来,下次在实在的页面未加载完成前,先展现这个缓存过的页面。
利用- // xxxx.json
- &#34;initialRenderingCache&#34;: &#34;static&#34;
复制代码 静态初始化衬着缓存
与静态初始化衬着缓存,静态初始化衬着缓存可以设备静态缓存的数据,放在onReady生命周期中
利用- // xxx.json
- &#34;initialRenderingCache&#34;: &#34;dynamic&#34;
- // xxx.js
- // 设备静态缓存数据
- this.setInitialRenderingCache({
- customersList: customerList
- })
复制代码 假如出现以下的信息,不用在意。
在手机里会有一条成功的信息:- update view with init data
复制代码 分包
小法式包巨细规定,单个代码包不跨越2MB,总包巨细不跨越20MB,所以到我们营业庞大,代码量大致使项目巨细上升,就必须用分包的形式,处理这个题目。
利用- // app.json
- {
- &#34;pages&#34;: [
- // &#34;pages/user/index&#34;
- ],
- &#34;subpackages&#34;: [
- {
- &#34;root&#34;: &#34;user&#34;,
- &#34;pages&#34;: [
- &#34;pages/user/index&#34;
- ]
- }
- ]
- }
复制代码 自力分包
利用- {
- &#34;pages&#34;: [
- // &#34;pages/user/index&#34;
- // &#34;pages/goods/index&#34;
- ],
- &#34;subpackages&#34;: [
- {
- &#34;root&#34;: &#34;user&#34;,
- &#34;pages&#34;: [
- &#34;pages/user/index&#34;
- ]
- },
- {
- &#34;root&#34;: &#34;goods&#34;,
- &#34;pages&#34;: [
- &#34;pages/goods/index&#34;
- ],
- &#34;independent&#34;: true // 自力分包关键设置
- }
- ]
- }
- // pages/goods/index.js
- const app = getApp({allowDefault: true}) // 自力分包中getApp为空,这里设备默许值
复制代码 自力分包以后拜候自力分包页面,主包和组件是不会被加载的,所以要分现实营业场景,停止分包
分包预加载
利用- &#34;preloadRule&#34;: {
- // 分包root途径+前面的途径
- &#34;goods/pages/detail/index&#34;: {
- &#34;network&#34;: &#34;all&#34;,
- &#34;packages&#34;: [
- &#34;__APP__&#34;
- ]
- }
- }
复制代码 看到这个提醒,暗示成功
总结
- tabbar最好自己实现
- 一切在根目录下的文件,假如没有分包,城市打包进主包,所以一般情况下,只放一个首页进主包
- 分包设置需要指定一个root目录,该目录下一切的文件城市自动被朋分到这个分包里
- 对于相对自力的页面(例如分享页),可以停止自力分包,自力分包的页面会有「返回首页的按钮」,一般队里分包里,都需要设备分包预加载
利用占位组件
利用占位组件提早加载自界说组件
利用 建立一个称号为index_addons的一个组件分包- // app.json
- &#34;subpackages&#34;: [
- {
- &#34;root&#34;: &#34;index_addons&#34;,
- &#34;pages&#34;: []
- }
- ]
复制代码 点窜主页设置- {
- &#34;componentPlaceholder&#34;: {
- &#34;stopwatch&#34;: &#34;view&#34; // 欲用作占位组件
- }
- }
复制代码 在stopwatch中增加代码
调试
假如没有这个选项,请确认能否有设置 &#34;lazyCodeLoading&#34;: [requiredComponents]
分包异步化
- require
- require.async 留意,只支持相对途径
利用- const { default: getNavList } = await require.async(&#34;../../../index_addons/compopnents/get_nav_list.js&#34;)
复制代码 视图代码优化技能
静态列表衬着里优化wx:key的利用
确保wx:key的值是唯一值
假如列表元素是单一的根基数据范例,而且是唯一的,这时辰我们可以间接写成this,这里这个this,就代表当前数据列内里面的数据元素- <view wx:for=&#34;{{textList}}&#34; wx:key=&#34;*this&#34;></view>
复制代码 假如列表元素是静态的,只衬着一次,那末可以间接用index- <view wx:for=&#34;{{swipers}}&#34; wx:key=&#34;index&#34;></view>
复制代码 假如数据是从背景获得的,那末wx:key需要有一个唯一值- <view wx:for=&#34;{{customerList}}&#34; wx:key=&#34;{{index}}&#34;></view>
复制代码 绑定视图事务
利用catch取代bind,削减dataset的数据运输量,由于我们在大大都情况下,我们的事务不需要冒泡,所以bind很浪费性能,catch是不会冒泡的,事务传递某些信息的时辰,需要什么传什么,不要一刀切,图省事,传递一个很大的工具,假如需要全部工具,倡议利用index停止传递- <view class=&#34;submit-btn&#34; catchbind=&#34;onViewDetail&#34; data-index=&#34;index&#34;>view detail</view>
复制代码 防抖&节省
节省
节省望文生义就是控制某段JS代码的履行频次- function throttle(method, wait = 50) {
- let previous = 0
- return function(...agrs) {
- let context = this
- let now = new Date().getTime()
- if(now - previouts > wait) {
- method.apply(context, args)
- previous = now
- } else {
- console.log(&#34;节省少许&#34;)
- }
- }
- }
复制代码 防抖
望文生义就是避免发抖,避免把一次时候当做屡次处置,敲击键盘就是一个经常城市碰到的防抖操纵场景- function debounce(func, wait = 50) {
- let timer = null
- return function (...args) {
- const contest = this
- if(timer) {
- clearTimeout(timer)
- console.log(&#34;防抖少许&#34;)
- }
- timer = setTimeout(() => {
- func.call(context, ...args)
- }, wait)
- }
- }
复制代码 组件中利用
- const {default:debounce} = require(../../../library/optimus/debounce.js)
- const {default:throttle} = require(../../../library/optimus/throttle.js)
- onScrolllToLower: throttle(function(e) {
- ...
- })
- onTapCustomerItem: debounce(function(e) {
- ..
- })
复制代码 只管少的利用重衬着和wxml标签
官方倡议:总页面节点数少于1000个,节点树深度层级少于30层,子节点数不大于60个 所以,在开辟进程中,能用<text>,就不用<view>,能用文本,就不用<text>,对于循环列表中,能用<block>就不用<view>
WXSS优化技能
给转动组件开启惯性转动
- -webkit-overflow-scrolling: touch;;
复制代码 利用hover-class实现按钮的单击态
- <button class=&#34;submit-btn&#34; hover-class=&#34;submit-btn__hover&#34;></button>
- .submit-btn {
- ...
- }
- .submit-btn__hover {
- ...
- }
复制代码 利用gulp工具删除无用的wxss款式代码
安装- npm install gulp -g
- npm install --save-dev gulp gulp-cleanwxss
复制代码 设置 /tools/gulpfile.js- const gulp = require(&#34;gulp&#34;)
- const cleanwxss = require(&#34;gulp-cleanwxss&#34;)
- // 处置父目录下的款式文件,输出到当前目录下的dist
- gulp.task(&#34;default&#34;, (done) => {
- group.src(&#34;../minniprogram/index/pages/*/*.wxss&#34;)
- .pipe(cleanwxss({ log: true }))
- .pipe(gulp.dest(&#34;./dist&#34;))
- done()
- })
- // 处置分包下的款式文件
- gulp.task(&#34;goods&#34;, (done) => {
- group.src(&#34;../minniprogram/goods/pages/*/*.wxss&#34;)
- .pipe(cleanwxss({ log: true }))
- .pipe(gulp.dest(&#34;./dist&#34;))
- done()
- })
复制代码 履行CV
将天生出来的款式文件复制到对应目录即可
UI交互优化技能
利用padding扩大可点击地区巨细
- .submit-btn {
- ...
- padding: 10px;
- }
复制代码 利用伪元素扩大可点击地区巨细
- .submit-btn {
- position: relative;
- ...
- }
- .submit-btn::after {
- content: &#39;&#39;,
- position: absolute;
- top: -20px;
- right: -20px;
- bottom: -20px;
- left: -20px;
-
- }
复制代码 剧本优化技能
清算按时器
利用wx.onXxx全局绑定,有一个监听,必须有一个反监听
- // 实时开释本页范围内增加的全局监听器
- onLoad() {
- wx.onThemeChange(this.themeChangeHandler)
- }
- onUnload() {
- wx.offThemeChange(this.themeChangeHandler)
- }
复制代码 模拟器测试需要在app.json中增加- &#34;darkMode&#34;: &#34;true&#34;
复制代码 谨慎利用全局工具,适那机会清算
setData挪用优化
不要屡次分隔挪用setData,只管合并
- // bad
- if(this.data.gender === &#39;1&#39;) {
- this.setData({
- genderName: &#39;男&#39;
- })
- } else if(this.data.gender === &#39;0&#39;) {
- this.setData({
- genderName: &#39;女&#39;
- })
- } else {
- this.setData({
- genderName: &#39;未知&#39;
- })
- }
- // good
- let genderName = &#39;未知&#39;
- if(this.data.gender === &#39;1&#39;) genderName = &#39;男&#39;
- if(this.data.gender === &#39;0&#39;) genderName = &#39;女&#39;
- this.setData({
- genderName,
- })
复制代码 不预备衬着的数据,不要放在data工具中
- Page({
- allList: [],
- pageNum: 1,
- pageSize: 10,
- data: {
- list: []
- }
- })
复制代码 经过index部分更新列表数据
- this.setData({
- [this.data.customerList[index].title]: item.title+=&#39;---&#39;
- })
复制代码 收集请求优化技能
削减不需要的收集请求,利用当地缓存数据
技术点:Storage
优化收集请求参数,进步收集请求效力
- enableCache: true,
- enableHttp2: true,
- enableQuic: true
复制代码 优化收集请求的并发数,分优先级
- npm i priority-async-queue
复制代码 request.js- const PriorityAsyncQueue = require(&#39;priority-async-queue&#39;)
- const queue = new PriorityAsyncQueue(10) // default 10
- const low = &#34;low&#34;, normal = &#34;normal&#34;, mid = &#34;mid&#34;, high = &#34;high&#34;, &#34;urgent&#34; = &#34;urgent&#34;
- export const priority = { low, normal, mid, high, urgent }
- ....
- return new Promise((resolve, reject) => {
- queue.addTask({ priority }. () => {
- wx.request(Object.assgin(args,{
- success: resolve,
- fail: reject
- })
- })
- })
复制代码 图片优化技能
削减图片的请求次数
紧缩图片巨细
尽能够利用CDN图片或图片链接
尽能够利用webp格式图片
结束
小法式的优化大致就是从这些背面动手了,感觉有用的同学,点个赞,收个藏吧! |