小程序优化之组件及wxs使用技巧

导航

一、利用组件来优化

二、利用wxs来优化

  • html其实会转化为JavaScript(DOM对象),所以html其实本质是js对象
  • 小程序采用自己的标签,用精简版wxs编写的xml。所以其实小程序页面是wxs对象
  • 但有需要js的完整能力,于是有两个独立线程(逻辑层js和渲染层wxs)
  • wxs和js是独立隔离的,并用Native来做中转,所以存在延时(需要通信)
  • js对wxs通信
  • setData()/其实onload时js执行了this.setData(data)=>所以设置值到页面是异步的
  • 其它比如wx.showToast、wx.setNavigationBarTitle这类和界面相关的,相当于是给页面默认的一个toast控件、NavigationBa,setdata()
  • 获取视图、节点信息 wx.getSystemInfo、wx.createSelectorQuery、wx.createIntersectionObserver=>所以获取视图节点信息是异步的
  • wxs对js通信
  • setData({},()=>{})的第二个参数,是setData的回调函数,相当于事件
  • 重复一遍:页面的事件,如果执行函数在js中,则执行是wxs对js通信
  • wxs中执行callMethod可以调用js的函数数据:√
  • 那wxs能做什么?:如果某项操作,页面交互比重大于js操作(或者交互方面操作多于js的操作),则推荐使用wxs
  • 由上图可知:小程序最大的优化点就是这两条线的通信
  • js对wxs的通信部分的优化:
  • 避免频繁setdata
  • 更新局部数据:setData({
    ['List[' + index + ']']: newItem,
    'obj.name':'hcl'
    })
  • 如果页面交互比重大于js操作,则获取页面节点信息操作可以让wxs来执行wxs优化点之一
  • wxs对js的通信部分优化:
  • 页面事件,如果页面交互比重大于js操作,则推荐事件绑定wxs函数
1.事件绑定js中的函数:
catch:tap="submitTap"
// 注意:这里绑定函数其实是字符串,执行时是根据这个字符串查找js中的对应函数

2.事件绑定wxs中的函数
catch:tap="{{m1.submitTap}}"
//这里是执行m1作用域中的submitTap函数。注意这里是变量。、
//对比以上,可以理解为还有个main作用域,是wxs中通信js的副本。
  • 其它如定时器/倒计时、动画 ,如果页面交互比重大于js操作也推荐采用wxs

总结
wxs是小程序页面原生脚本,所以页面相关的处理,wxs是同步的实时的
如果你的小程序纯粹js来处理来处理逻辑,wxs是可以优化的方向!
wxs除了用于减少通信,还可以用于计算属性:
小程序页面xml本质就是wxs嘛,所以可以直接访问wxs数据,而不能同步访问js数据

  • 左右互搏--老顽童
  • 本篇文章其实是认识小程序页面的原理,及双线程的原因及认识js和wxs直接的关系
  • 目的是希望:js和wxs能够左右互搏,两只手都发挥最大作用,进而提升小程序的效率!

2.实战----关于滑动后指定组件吸附置顶效果

A:第一种方式:传统方法
//第一步:获取节点到顶端的距离
// 计算分类icon到头部的距离
NodeToTopDistance(name,id){
     const query = wx.createSelectorQuery()
     query.select("#"+id).boundingClientRect()
     query.exec((res)=>{
     this.data[name]=res[0].top+res[0].height;
     this.setData({
         [name]:res[0].top+res[0].height
     })
     console.log("计算出来的距离:",name,this.data[name],res[0].top,res[0].height,res[0])
     })
},
 this.NodeToTopDistance("sortBarToTopDistance","sortBar")

//第二步,页面绑定滚动监听
onPageScroll(e){
    if(!this.data.scrollTimeout){//没有开始计时则开始计时
        this.pageScrollHandle(e);//处理逻辑函数
        this.data.scrollTimeout=setTimeout(() => {
            this.pageScrollHandle( this.data.pageScrollEvent);//处理逻辑函数
            delete this.data.scrollTimeout;
        }, 50);
    }else{//开始计时了则保存最后一次的e
        this.data.pageScrollEvent=e;
    }
},

第一种方式缺点:
js通过setData频繁的和wxs通信。页面数据多时,会有明显卡顿现象

B:第二种方式:wxs中执行事件
//第一步:获取节点到顶端的距离
// 计算分类icon到头部的距离
NodeToTopDistance(name,id){
     const query = wx.createSelectorQuery()
     query.select("#"+id).boundingClientRect()
     query.exec((res)=>{
     this.data[name]=res[0].top+res[0].height;
     this.setData({
         [name]:res[0].top+res[0].height
     })
     console.log("计算出来的距离:",name,this.data[name],res[0].top,res[0].height,res[0])
     })
},
 this.NodeToTopDistance("sortBarToTopDistance","sortBar")

//第二步:修改下xml。这样才能绑定执行wxs函数
<scroll-view data-totopheight="{{sortBarToTopDistance}}"  bindscroll="{{_wxs.scrollHandle}}">
    。。。
    。。。
</scroll-view>

//第三步,在wxs中,执行
var scrollTimeout;
var pageScrollEvent;

var scrollHandle=function(e,ins){
    if(!scrollTimeout){//没有开始计时则开始计时
        xx(e,ins)
        scrollTimeout=setTimeout(function(){
            xx(pageScrollEvent,ins)
            scrollTimeout=undefined;
        }, 50);
    }else{//开始计时了则保存最后一次的e
        pageScrollEvent=e;
    }
}
var xx=function(e,ins){
    var dataset =  e.instance.getDataset();
    //获取sortBar组件实例 
    var sortBar=ins.selectComponent("#sortBarContent")
    // 获取搜索条组件实例
    var search=ins.selectComponent("#search")
    var sortBarToTopHeight=dataset.totopheight;
    if(!sortBarToTopHeight) return ;//还没有获取到sortBar到顶端的距离。则不执行底下内容
    else if(e.detail.scrollTop>sortBarToTopHeight){//开启 悬浮置顶
        //isOpenToFixed=true;
        console.log("fixed")
        sortBar.addClass("fixed");
        search.addClass("fixed");
    }else{//关闭 悬浮置顶
        //isOpenToFixed=false;
        console.log("removeFixed")
        sortBar.removeClass("fixed");
        search.removeClass("fixed");
    }
}

module.exports = { 
    scrollHandle:scrollHandle
};

第二种方式的优点:
从wxs获取节点接口可以发现:wxs获取节点是同步的 √(验证了xml其实就是wxs模型)
避免了js和wxs直接的通信,发现可以提升使用体验

C:第三种方式: wx.createIntersectionObserverd接口
//第一步:定义处理逻辑
intersectionObserver(){
    this._observer = wx.createIntersectionObserver()
    this._observer
        .relativeToViewport({})
        .observe('#sortBar', (res) => {
            console.log(res)
            /* 
            1:移出时,目标全都不可见,即:intersectionRatio==0
            2:移入时,目标肯定是部分区域已经可视,即:intersectionRatio>0
            3: 移出判断向上、向下移出,则判断res.intersectionRatio==0 && boundingClientRect的top。top为负数,则是在视图上面,即向上移出
            4. 移入判断向上、向下移入,则判断boundingClientRect.bottom<relativeRect.bottom/2说明是上半屏。即向下移入
            5. 因为是相交区域的上下左右边界。所以移出【全都移出才会触发这个函数】看top。移入【有部分可见就会触发这个函数】看bottom
            6:只在切换可见、不可见时才会触发这个回调函数:显然是较好的方案
            */
        if(res.intersectionRatio==0 && res.boundingClientRect.top<0){//向上移出
            this.setData({
                isOpenToFixed:true
            })
        }else if(res.intersectionRatio>0 && res.boundingClientRect.bottom<res.relativeRect.bottom/2){//向下移入
            this.setData({
                isOpenToFixed:false
            })
        }
        })
},

//但要注意一点
onUnload() {
    if (this._observer) this._observer.disconnect()
},

第三种方式优点:
代码少
只在必要的时候触发回调函数(移入移出时才触发)。高效!

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

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,094评论 1 32
  • 因新工作主要负责微信小程序这一块,最近的重心就移到这一块,该博客是对微信小程序整体的整理归纳以及标明一些细节点,初...
    majun00阅读 7,332评论 0 9
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,456评论 1 45
  • 一.微信小程序是啥 本质其实就是(混合)的app 介于web app与native 原生app之间,具备丰富的调用...
    向日葵666666阅读 1,344评论 0 0
  • 有人过成了苍老的苟且,有人却越过越年轻,过成了诗和远方? “小时不识月,呼作白玉盘。又疑瑶台镜,飞在青云端” 好奇...
    烨子墨阅读 434评论 0 7