小程序备忘

小程序开发工具--详情--本地设置--启用自定义处理命令
用来执行脚本

“右滑手势返回”能力调整

为了提升用户操作的流畅性,同时让用户在微信内拥有一致的操作体验,“右滑手势返回”将成为基础配置,即所有小程序内都可以从屏幕左侧边缘向右滑动返回上一个界面。 在即将发布的7.0.5客户端版本中,页面配置中的 disableSwipeBack 属性将不再生效,请开发者及时调整。

顶部固定,且支持下拉刷新

  data: {
    bgTop: 0,
  },
  onPageScroll: function (e) {
    setData({
      bgTop: e.scrollTop
    });
  },
.bg-image {
  position: fixed;
  width: 100%;
  top: bgTop; 
}

背景图为fixed,top随滚动而改变重点就是onPageScroll

以上为错误示范,其实重点是bgTop: 0,不能直接top: 0。onPageScroll也是没必要的。android机型上不需要做任何设置,ios上设置了也没用。

还可使用 scroll-view 的下拉刷新,且可以自定义样式。
用wxs监听滚动事件,设置样式。

request域名问题

不在以下 request 合法域名列表中,请参考文档
解决方案:在详情--本地设置中勾选“不校验合法域名。。。”

image

mode widthFix 缩放模式,宽度不变,高度自动变化,保持原图宽高比不变。应避免使用widthFix,尽量指定宽高。

<image mode="widthFix" src="{{src}}"></image>

自定义NavBar

导航栏高度
iOS 44px (4+32+8)
android 48px (8+32+8)

胶囊与状态栏间距(应该计算得出)ios 4px,Android 8px,与导航栏底边距8px(只能取固定值)。
胶囊高度 32px

let rect = wx.getMenuButtonBoundingClientRect()
console.log(rect.height) // 32

状态栏高度,刘海屏通常为44px

let info = wx.getSystemInfoSync()
console.log(info.statusBarHeight) // 44

页面切换优化

  • 提前发起数据请求:在一些对性能要求比较高的场景下,当使用 JSAPI 进行页面跳转时(例如 wx.navigateTo),可以提前为下一个页面做一些准备工作。页面之间可以通过 EventChannel 进行通信。例如,在页面跳转时,可以同时发起下一个页面的数据请求,而不需要等到页面 onLoad 时再进行,从而可以让用户更早的看到页面内容。

资源加载优化

  • 避免滥用 image 组件的 widthFix/heightFix 模式:
    widthFix/heightFix 模式会在图片加载完成后,动态改变图片的高度或宽度。图片高度或宽度的动态改变,可能会引起页面内大范围的布局重排,导致页面发生抖动,并造成卡顿。

    对于页面的背景图或 banner 图,应尽量预先指定图片的尺寸,避免图片加载完成后再进行二次的尺寸调整。

渲染性能优化

  • 适当监听页面或组件的 scroll 事件
    只要用户在 Page 构造时传入了 onPageScroll 监听,基础库就会认为开发者需要监听页面 scoll 事件。此时,当用户滑动页面时,事件会以很高的频率从视图层发送到逻辑层,存在一定的通信开销。
    不需要监听事件时,Page 构造时应不传入 onPageScroll 函数。
Page({
  onPageScroll () {} // ❌不要保留空函数
})

Page({ 
  // ✅ 应直接不传入
})

合理使用 setData

setData 是小程序开发中使用最频繁、也是最容易引发性能问题的接口。

  1. setData 的过程,大致可以分成几个阶段:
  • 逻辑层虚拟 DOM 树的遍历和更新,触发组件生命周期和 observer 等;
  • 将 data 从逻辑层传输到视图层;
  • 视图层虚拟 DOM 树的更新、真实 DOM 元素的更新并触发页面渲染更新。
  1. data 应只包括渲染相关的数据
    setData 应只用来进行渲染相关的数据更新。用 setData 的方式更新渲染无关的字段,会触发额外的渲染流程,或者增加传输的数据量,影响渲染耗时。
  • ✅ 页面或组件的 data 字段,应用来存放和页面或组件渲染相关的数据(即直接在 wxml 中出现的字段);
  • ✅ 页面或组件渲染间接相关的数据可以设置为「纯数据字段」,可以使用 setData 设置并使用 observers 监听变化;
  • ✅ 页面或组件渲染无关的数据,应挂在非 data 的字段下,如 this.userData = {userId: 'xxx'}
  • ❌ 避免在 data 中包含渲染无关的业务数据;
  • ❌ 避免使用 data 在页面或组件方法间进行数据共享
  • ❌ 避免滥用 纯数据字段 来保存可以使用非 data 字段保存的数据。
  1. 控制 setData 的频率
    每次 setData 都会触发逻辑层虚拟 DOM 树的遍历和更新,也可能会导致触发一次完整的页面渲染流程。过于频繁(毫秒级)的调用 setData,会导致以下后果:
  • 逻辑层 JS 线程持续繁忙,无法正常响应用户操作的事件,也无法正常完成页面切换;
  • 视图层 JS 线程持续处于忙碌状态,逻辑层 -> 视图层通信耗时上升,视图层收到消息的延时较高,渲染出现明显延迟;
  • 视图层无法及时响应用户操作,用户滑动页面时感到明显卡顿,操作反馈延迟,用户操作事件无法及时传递到逻辑层,逻辑层亦无法及时将操作处理结果及时传递到视图层。

因此,开发者在调用 setData 时要注意:

  • ✅ 仅在需要进行页面内容更新时调用 setData;
  • ✅ 对连续的 setData 调用尽可能的进行合并
  • ❌ 避免不必要的 setData;
  • ❌ 避免以过高的频率持续调用 setData,例如毫秒级的倒计时;
  • ❌ 避免在 onPageScroll 回调中每次都调用 setData。
  1. 选择合适的 setData 范围
    组件的 setData 只会引起当前组件和子组件的更新,可以降低虚拟 DOM 更新时的计算开销。
  • ✅ 对于需要频繁更新的页面元素(例如:秒杀倒计时),可以封装为独立的组件,在组件内进行 setData 操作。必要时可以使用 CSS contain 属性限制计算布局、样式和绘制等的范围。
  1. setData 应只传发生变化的数据
    setData 的数据量会影响数据拷贝和数据通讯的耗时,增加页面更新的开销,造成页面更新延迟。
  • ✅ setData 应只传入发生变化的字段;
  • ✅ 建议以数据路径形式改变数组中的某一项或对象的某个属性,如 this.setData({'array[2].message': 'newVal', 'a.b.c.d': 'newVal'}),而不是每次都更新整个对象或数组;
  • ❌ 不要在 setData 中偷懒一次性传所有data:this.setData(this.data)
  1. 控制后台态页面的 setData
    由于小程序逻辑层是单线程运行的,后台态页面去 setData 也会抢占前台页面的运行资源,且后台态页面的的渲染用户是无法感知的,会产生浪费。在某些平台上,小程序渲染层各 WebView 也是共享同一个渲染线程,后台页面的渲染也会导致前台页面的卡顿。
    ✅ 页面切后台后的更新操作,应尽量避免,或延迟到页面 onShow 后延迟进行;
    ❌ 避免在切后台后仍进行高频的 setData,例如倒计时更新。

使用setData更新变量

  changeItemInArray: function() {
    // 对于对象或数组字段,可以直接修改一个其下的子字段,这样做通常比修改整个对象或数组更好
    this.setData({
      'array[0].text':'changed data'
    })
  },
  changeItemInObject: function(){
    this.setData({
      'object.text': 'changed data'
    });
  },
  addNewField: function() {
    this.setData({
      'newField.text': 'new data'
    })
  }

数组索引不能直接用变量,解决方案:

var like = `movielist[${id}].like`
this.setData({
  [like]: 'like'
})

取原来的值:

    let {
      list
    } = this.data;
    let key = `list[${idx}].show`;
    let show = list[idx].show;
    this.setData({
      [key]: !show
    });

小程序倒计时

  startCoundown(seconds) {
    let {
      timer
    } = this.data;
    if (timer) {
      clearInterval(timer);
    }
    let countdown = app.formatSeconds(seconds);
    this.setData({
      'orderInfo.countdown': countdown
    });
    timer = setInterval(() => {
      seconds--;
      countdown = app.formatSeconds(seconds);
      if (seconds > 0) {
        this.setData({
          'orderInfo.countdown': countdown
        });
      } else {
        clearInterval(timer);
        this.getOrderInfo();
      }
    }, 1000);
    this.data.timer = timer;
  },

注意timer的赋值this.data.timer = timer;
考虑到下拉刷新,要在startCountdown中取消timer

在onUnload中取消timer

  onUnload: function () {
    let {
      timer
    } = this.data;
    if (timer) {
      clearInterval(timer);
    }
  },

hover-class

微信小程序中,可以用 hover-class 属性来指定元素的点击态效果。但是在在使用中要注意,大部分组件是不支持该属性的。

目前支持 hover-class 属性的组件有三个:view、button、navigator。

不支持 hover-class 属性的组件,同时也不支持 hover-stop-propagation、hover-start-time、hover-stay-time 这三个属性。

background

如果background写在wxml中,那么background-size也要写在style中,如果写在wxss中不会生效。

小程序 safe-area-inset-bottom iphoneX

获取系统屏幕边框的安全距离:

safe-area-inset-top
safe-area-inset-right
safe-area-inset-bottom
safe-area-inset-left

ios11:constant(safe-area-inset-bottom)
ios11.2:env(safe-area-inset-bottom)

scroll-view

scroll-view的子元素最好包一层,不然宽度可能不起作用。

遮罩层禁止滚动

当小程序使用页面进行滚动时,可以给遮罩设置catchtouchmove属性来禁止页面滚动

<view class="mask" catchtouchmove="true"></view>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,729评论 6 342
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,894评论 2 89
  • 不知不觉已经与大家一起共读了萌姐3本书籍《让你的时间更有价值》、《从受欢迎到被需要》和《引爆视频号》,萌姐目前...
    开心写作洁阅读 394评论 0 3
  • 一:小程序云开发的基本页面结构 1.cloudfunctions是指定腾讯云开发的项目目录 2.miniprogr...
    jjbnxy阅读 3,373评论 0 2
  • 第一章第一节为什么要学编程30年前,编程可能只是计算机行业才需要的技能。到了今天,编程已经成为数学、金融、物理、教...
    小正歪阅读 168评论 0 0