找回密码
 立即注册

【小程序】爆肝 3 天总结的微信小程序优化指南(收藏夹吃灰 ...

匿名  发表于 2022-9-19 12:13:58 阅读模式 打印 上一主题 下一主题
前言

大师好,我是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 监听页面卸载
优化技能

利用骨架屏

骨架屏的目标是为了减缓用户期待的情感
利用
如图,在小法式开辟者工具中,点击这里,天生骨架屏代码

【小法式】爆肝 3 天总结的微信小法式优化指南(收藏夹吃灰 ...-1.jpg

然后他会天生两个文件:index.skeleton.wxml & index.skeleton.wxss
别离在index.wxml & index.wxss引入

【小法式】爆肝 3 天总结的微信小法式优化指南(收藏夹吃灰 ...-2.jpg

总结

  • 在data数据工具中默许设备loading即是true。
  • 不要间接点窜天生的骨架屏的一个代码。经过设置去点窜。
  • **不要过度去利用骨架屏。一般只给主页去增加骨架屏结果 **
优化长列表

优化长列表,利用recycle-view & recycle-item 虚拟DOM组件,在衬着的时辰需要晓得每个循环单元的一个高度,这是消耗代码需要传递给组件的,在recycle-view组件里面,用户滑动的是数据而不是组件自己。
利用 首先初始化package.json
  1. // npm初始化package.json文件
  2. npm init -y
复制代码
安装
  1. // 安装 miniprogram-recycle-view插件
  2. npm install --save miniprogram-recycle-view
复制代码
构建依靠

【小法式】爆肝 3 天总结的微信小法式优化指南(收藏夹吃灰 ...-3.jpg
天生miniprogram_npm目录

【小法式】爆肝 3 天总结的微信小法式优化指南(收藏夹吃灰 ...-4.jpg

组件内援用

【小法式】爆肝 3 天总结的微信小法式优化指南(收藏夹吃灰 ...-5.jpg

代码中利用
list.wxml
  1. <recycle-view batch="{{batchSetRecycleData}}" id="recycleId" catchscroll="onScroll">
  2.   <view slot="before">长列表前面的内容</view>
  3.   <recycle-item wx:for="{{recycleList}}" wx:key="id">
  4.     <view>
  5.         <image style='width:80px;height:80px;float:left;' src="{{item.image_url}}"></image>
  6.       {{item.idx+1}}. {{item.title}}
  7.     </view>
  8.   </recycle-item>
  9.   <view slot="after">长列表前面的内容</view>
  10. </recycle-view>
复制代码
list.js
  1. const createRecycleContext = require('miniprogram-recycle-view')
  2. Page({
  3.   onReady: function () {
  4.     var ctx = createRecycleContext({
  5.       id: 'recycleId',
  6.       dataKey: 'recycleList',
  7.       page: this,
  8.       itemSize: this.itemSizeFunc
  9.     })
  10.     ctx.append([{
  11.       image_url: 'https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/09883c4389f642829c96b6216eebea85~tplv-k3u1fbpfcp-watermark.image?',
  12.       idx: 1,
  13.       title: '你好'
  14.     }])
  15.     // ctx.update(beginIndex, list)
  16.     // ctx.destroy()
  17.   },
  18.   onScroll() {
  19.     console.log('scroll')
  20.   },
  21.   itemSizeFunc: function (item, idx) {
  22.     console.log(item)
  23.     return {
  24.       width: 375,
  25.       height: 100
  26.     }
  27.   }
  28. })
复制代码
总结
代码写起来不是那末舒服,组件利用不友爱,可是对性能确切还不错。
利用页面庞器

偶然辰我们在页面上会弹出一些特定的半屏窗口,例如登录窗口。这时辰假如用户在iOS装备上利用了左滑手势大概是在Android设惫亓击了物理返回键,会形成页面跳转到上一个页面,这在大大都情况下它并不是用户的实在本意,用户能够只是想将当前弹出的半屏的假页面给它关掉。
page-container页面庞器,是不需要引入即可以利用。
利用
  1. <page-container :show="{{show}}">
  2.     ...
  3. </page-container>
复制代码
总结
这个组件实在就是避免用户的左滑大概按键返回误操纵,致使全部页面回退的题目。
优化动画结果

实现动画的方式:

  • 是利用Animation工具,实现CSS动画
  • 利用页面或组件工具,具有的animate方式实现的关键帧动画
  • 利用转动事务驱动的响应式动画
  • 经过WXS剧本,实现了一个款式动画
  • 经过第三方库实现animate.css
代码按需注入

代码懒加载
利用
  1. // app.json
  2. "lazyCodeLoading": "requiredComponents"
复制代码
出现以下提醒,代表成功

【小法式】爆肝 3 天总结的微信小法式优化指南(收藏夹吃灰 ...-6.jpg

静态初始化衬着缓存

第一次页面运转时,由微信客户端负责将页面在当地的某个地区缓存起来,下次在实在的页面未加载完成前,先展现这个缓存过的页面。
利用
  1. // xxxx.json
  2. "initialRenderingCache": "static"
复制代码
静态初始化衬着缓存

与静态初始化衬着缓存,静态初始化衬着缓存可以设备静态缓存的数据,放在onReady生命周期中
利用
  1. // xxx.json
  2. "initialRenderingCache": "dynamic"
  3. // xxx.js
  4. // 设备静态缓存数据
  5. this.setInitialRenderingCache({
  6.     customersList: customerList
  7. })
复制代码
假如出现以下的信息,不用在意。

【小法式】爆肝 3 天总结的微信小法式优化指南(收藏夹吃灰 ...-7.jpg

在手机里会有一条成功的信息:
  1. update view with init data
复制代码
分包

小法式包巨细规定,单个代码包不跨越2MB,总包巨细不跨越20MB,所以到我们营业庞大,代码量大致使项目巨细上升,就必须用分包的形式,处理这个题目。
利用
  1. // app.json
  2. {
  3.     "pages": [
  4.         // "pages/user/index"
  5.     ],
  6.     "subpackages": [
  7.         {
  8.             "root": "user",
  9.             "pages": [
  10.                 "pages/user/index"
  11.             ]
  12.         }
  13.     ]
  14. }
复制代码
自力分包

利用
  1. {
  2.     "pages": [
  3.         // "pages/user/index"
  4.         // "pages/goods/index"
  5.     ],
  6.     "subpackages": [
  7.         {
  8.             "root": "user",
  9.             "pages": [
  10.                 "pages/user/index"
  11.             ]
  12.         },
  13.         {
  14.             "root": "goods",
  15.             "pages": [
  16.                 "pages/goods/index"
  17.             ],
  18.             "independent": true // 自力分包关键设置
  19.         }
  20.     ]
  21. }
  22. // pages/goods/index.js
  23. const app = getApp({allowDefault: true}) // 自力分包中getApp为空,这里设备默许值
复制代码
自力分包以后拜候自力分包页面,主包和组件是不会被加载的,所以要分现实营业场景,停止分包
分包预加载

利用
  1. "preloadRule": {
  2. // 分包root途径+前面的途径
  3.     "goods/pages/detail/index": {
  4.         "network": "all",
  5.         "packages": [
  6.             "__APP__"
  7.         ]
  8.     }
  9. }
复制代码
看到这个提醒,暗示成功

【小法式】爆肝 3 天总结的微信小法式优化指南(收藏夹吃灰 ...-8.jpg

总结

  • tabbar最好自己实现
  • 一切在根目录下的文件,假如没有分包,城市打包进主包,所以一般情况下,只放一个首页进主包
  • 分包设置需要指定一个root目录,该目录下一切的文件城市自动被朋分到这个分包里
  • 对于相对自力的页面(例如分享页),可以停止自力分包,自力分包的页面会有「返回首页的按钮」,一般队里分包里,都需要设备分包预加载
利用占位组件

利用占位组件提早加载自界说组件
利用 建立一个称号为index_addons的一个组件分包
  1. // app.json
  2. "subpackages": [
  3.     {
  4.         "root": "index_addons",
  5.         "pages": []
  6.     }
  7. ]
复制代码
点窜主页设置
  1. {
  2.     "componentPlaceholder": {
  3.         "stopwatch": "view" // 欲用作占位组件
  4.     }
  5. }
复制代码
在stopwatch中增加代码

【小法式】爆肝 3 天总结的微信小法式优化指南(收藏夹吃灰 ...-9.jpg

调试

  • 设备为2g网
  • 当地设备里,设备懒注入占位组件调试


【小法式】爆肝 3 天总结的微信小法式优化指南(收藏夹吃灰 ...-10.jpg
假如没有这个选项,请确认能否有设置 "lazyCodeLoading": [requiredComponents]
分包异步化


  • require
  • require.async 留意,只支持相对途径
利用
  1. const { default: getNavList } = await require.async("../../../index_addons/compopnents/get_nav_list.js")
复制代码
视图代码优化技能

静态列表衬着里优化wx:key的利用

确保wx:key的值是唯一值
假如列表元素是单一的根基数据范例,而且是唯一的,这时辰我们可以间接写成this,这里这个this,就代表当前数据列内里面的数据元素
  1. <view wx:for="{{textList}}" wx:key="*this"></view>
复制代码
假如列表元素是静态的,只衬着一次,那末可以间接用index
  1. <view wx:for="{{swipers}}" wx:key="index"></view>
复制代码
假如数据是从背景获得的,那末wx:key需要有一个唯一值
  1. <view wx:for="{{customerList}}" wx:key="{{index}}"></view>
复制代码
绑定视图事务

利用catch取代bind,削减dataset的数据运输量,由于我们在大大都情况下,我们的事务不需要冒泡,所以bind很浪费性能,catch是不会冒泡的,事务传递某些信息的时辰,需要什么传什么,不要一刀切,图省事,传递一个很大的工具,假如需要全部工具,倡议利用index停止传递
  1. <view class="submit-btn" catchbind="onViewDetail" data-index="index">view detail</view>
复制代码
防抖&节省

节省

节省望文生义就是控制某段JS代码的履行频次
  1. function throttle(method, wait = 50) {
  2.     let previous = 0
  3.     return function(...agrs) {
  4.         let context = this
  5.         let now = new Date().getTime()
  6.         if(now - previouts > wait) {
  7.             method.apply(context, args)
  8.             previous = now
  9.         } else {
  10.             console.log("节省少许")
  11.         }
  12.     }
  13. }
复制代码
防抖

望文生义就是避免发抖,避免把一次时候当做屡次处置,敲击键盘就是一个经常城市碰到的防抖操纵场景
  1. function debounce(func, wait = 50) {
  2.     let timer = null
  3.     return function (...args) {
  4.         const contest = this
  5.         if(timer) {
  6.             clearTimeout(timer)
  7.             console.log("防抖少许")
  8.         }
  9.         timer = setTimeout(() => {
  10.             func.call(context, ...args)
  11.         }, wait)
  12.     }
  13. }
复制代码
组件中利用
  1. const {default:debounce} = require(../../../library/optimus/debounce.js)
  2. const {default:throttle} = require(../../../library/optimus/throttle.js)
  3. onScrolllToLower: throttle(function(e) {
  4.     ...
  5. })
  6. onTapCustomerItem: debounce(function(e) {
  7.     ..
  8. })
复制代码
只管少的利用重衬着和wxml标签

官方倡议:
总页面节点数少于1000个,节点树深度层级少于30层,子节点数不大于60个
所以,在开辟进程中,能用<text>,就不用<view>,能用文本,就不用<text>,对于循环列表中,能用<block>就不用<view>

【小法式】爆肝 3 天总结的微信小法式优化指南(收藏夹吃灰 ...-11.jpg

WXSS优化技能

给转动组件开启惯性转动
  1. -webkit-overflow-scrolling: touch;;
复制代码
利用hover-class实现按钮的单击态
  1. <button class="submit-btn" hover-class="submit-btn__hover"></button>
  2. .submit-btn {
  3.     ...
  4. }
  5. .submit-btn__hover {
  6.     ...
  7. }
复制代码
利用gulp工具删除无用的wxss款式代码

安装
  1. npm install gulp -g
  2. npm install --save-dev gulp gulp-cleanwxss
复制代码
设置 /tools/gulpfile.js
  1. const gulp = require("gulp")
  2. const cleanwxss = require("gulp-cleanwxss")
  3. // 处置父目录下的款式文件,输出到当前目录下的dist
  4. gulp.task("default", (done) => {
  5.     group.src("../minniprogram/index/pages/*/*.wxss")
  6.         .pipe(cleanwxss({ log: true }))
  7.         .pipe(gulp.dest("./dist"))
  8.      done()
  9. })
  10. // 处置分包下的款式文件
  11. gulp.task("goods", (done) => {
  12.     group.src("../minniprogram/goods/pages/*/*.wxss")
  13.         .pipe(cleanwxss({ log: true }))
  14.         .pipe(gulp.dest("./dist"))
  15.      done()
  16. })
复制代码
履行
  1. gulp default
  2. gulp goods
复制代码
CV
将天生出来的款式文件复制到对应目录即可
UI交互优化技能

利用padding扩大可点击地区巨细
  1. .submit-btn {
  2.     ...
  3.     padding: 10px;
  4. }
复制代码
利用伪元素扩大可点击地区巨细
  1. .submit-btn {
  2.     position: relative;
  3.     ...
  4. }
  5. .submit-btn::after {
  6.     content: '',
  7.     position: absolute;
  8.     top: -20px;
  9.     right: -20px;
  10.     bottom: -20px;
  11.     left: -20px;
  12.    
  13. }
复制代码
剧本优化技能

清算按时器
  1. clearTimeout(timer1)
复制代码
利用wx.onXxx全局绑定,有一个监听,必须有一个反监听
  1. // 实时开释本页范围内增加的全局监听器
  2. onLoad() {
  3.     wx.onThemeChange(this.themeChangeHandler)
  4. }
  5. onUnload() {
  6.     wx.offThemeChange(this.themeChangeHandler)
  7. }
复制代码
模拟器测试需要在app.json中增加
  1. "darkMode": "true"
复制代码
谨慎利用全局工具,适那机会清算

setData挪用优化

不要屡次分隔挪用setData,只管合并
  1. // bad
  2. if(this.data.gender === '1') {
  3.     this.setData({
  4.         genderName: '男'
  5.     })
  6. } else if(this.data.gender === '0') {
  7.     this.setData({
  8.         genderName: '女'
  9.     })
  10. } else {
  11.     this.setData({
  12.         genderName: '未知'
  13.     })
  14. }
  15. // good
  16. let genderName = '未知'
  17. if(this.data.gender === '1') genderName = '男'
  18. if(this.data.gender === '0') genderName = '女'
  19. this.setData({
  20.     genderName,
  21. })
复制代码
不预备衬着的数据,不要放在data工具中
  1. Page({
  2.     allList: [],
  3.     pageNum: 1,
  4.     pageSize: 10,
  5.     data: {
  6.         list: []
  7.     }
  8. })
复制代码
经过index部分更新列表数据
  1. this.setData({
  2.     [this.data.customerList[index].title]: item.title+='---'
  3. })
复制代码
收集请求优化技能

削减不需要的收集请求,利用当地缓存数据

技术点:Storage
优化收集请求参数,进步收集请求效力
  1. enableCache: true,
  2. enableHttp2: true,
  3. enableQuic: true
复制代码
优化收集请求的并发数,分优先级
  1. npm i priority-async-queue
复制代码
request.js
  1. const PriorityAsyncQueue = require('priority-async-queue')
  2. const queue = new PriorityAsyncQueue(10) // default 10
  3. const low = "low", normal = "normal", mid = "mid", high = "high", "urgent" = "urgent"
  4. export const priority = { low, normal, mid, high, urgent }
  5. ....
  6. return new Promise((resolve, reject) => {
  7.     queue.addTask({ priority }. () => {
  8.         wx.request(Object.assgin(args,{
  9.             success: resolve,
  10.             fail: reject
  11.         })
  12.     })
  13. })
复制代码
图片优化技能

削减图片的请求次数

紧缩图片巨细

尽能够利用CDN图片或图片链接

尽能够利用webp格式图片

结束

小法式的优化大致就是从这些背面动手了,感觉有用的同学,点个赞,收个藏吧!
回复

使用道具

说点什么

您需要登录后才可以回帖 登录 | 立即注册
HOT • 推荐

神回复

站长姓名:王殿武 杭州共生网络科技 创始人 云裂变新零售系统 创始人 飞商人脉对接平台 创始人 同城交友聚会平台 创始人 生活经验分享社区 创始人 合作微信:15924191378(注明来意)