前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >干货|小程序性能优化的几点实践技巧

干货|小程序性能优化的几点实践技巧

作者头像
腾讯NEXT学位
发布2019-08-27 09:40:37
1.4K0
发布2019-08-27 09:40:37
举报
文章被收录于专栏:腾讯NEXT学位腾讯NEXT学位

我们都知道,性能的好坏直接影响用户的体验。本文首先论述下如何评判一个小程序页面的性能情况,之后通过具体的案例重点讲解下几点实践技巧,最后再讲讲key值在渲染一个列表时发挥了一个怎么样的作用,以此来论述为啥key值对性能提升有帮助。

实践技巧一

1

存在setData的数据过大

我们的功能里面有个滚动到底部加载的功能,优化前我们的做法是这样的:

代码语言:javascript
复制
<!--只阐述逻辑,非真实代码-->

// 1: 初始一个list,存储列表数据
data = startList
// 2: 监听滚动事件,滚动到底部获取新数据,并追加到list尾部,最后重新setData
onReachBottom:()=>{
    const {list} = this.data
    fetchNewData().then((res)=>{
        list.push(res.list);
        this.setData({list})
    }
}

估计大部分人面对长列表滚动的时候,一开始的处理方式都是这样的,如果数据不多,只有几页可能不会太暴露问题,如果页数过多,几十页甚至上百页的情况,list的数据会越来越大,每次setData的数据就会越来越多,因而每次页面重新渲染的节点就会越来越多,从而导致滚动到后面,加载越来越慢。

另外,由于小程序的视图渲染层和数据逻辑处理层是分开的,不是在同一个线程上面的,从用户触发页面交互,到处理数据逻辑,最后层现页面,数据到视图是需要传输的,因而小程序本身对数据大小也有限制,不能超过1M

2

setData数据路径

怎么解决呢?小程序setData里面的key支持数据路径的写法,比如:

代码语言:javascript
复制
let o = obj;
this.setData({
    'o.属性':value
})

或者
let a = array;
this.setData({
    'array[0].text':value
})

所以我们可以通过数据路径的写法,来将数据分批的传输到视图层中,减少一次性setData的数据大小。具体写法如下:

代码语言:javascript
复制
// 1.通过一个二维数组来存储数据
let feedList = [[array]];

// 2.维护一个页面变量值,加载完一次数据page++
let page = 1

// 3.页面每次滚动到底部,通过数据路径更新数据
onReachBottom:()=>{
    fetchNewData().then((newVal)=>{
        this.setData({
            ['feedList[' + (page - 1) + ']']: newVal,
        })
    }
}
// 4.最终我们的数据是[[array1],[array2]]这样的格式,然后通过wx:for遍历渲染数据

实践技巧二

1

存在短时间内发起太多图片请求

这个应该好理解,就是渲染页面时,一次性发送了过多的图片请求,导致了同一时间发起了过多的http请求,http连接是非常耗时的,尤其是一次性发起这么多,并且一次性发起的http链接也是有限制的,比如chrome浏览器就限制一次性最多6个。 所以在渲染页面时,不在视图范围内的图片我们不加载,只有元素出现在视图范围内了,再渲染。 常规的做法是,通过

getBoundingClientRect()获取元素的位置,然后与页面滚动位置比较,如果出现在视图内,就将 img 显示。这种方式有2个问题: ①getBoundingClientRect()方法调用本身容易引起页面重排。 ②监听滚动事件本身就频繁触发,虽然可以通过节流的方式来减少,但还是容易增加无谓代码处理。

2

IntersectionObserver

其实,微信提供了 IntersectionObserver 对象。 IntersectionObserver 对象,用于推断某些节点是否可以被用户看见、有多大比例可以被用户看见 通过这个api我们不用再主动去监听元素位置了,在页面渲染一开始,通过这个api指明需要监听的元素,系统会自动去监听了元素位置。

代码语言:javascript
复制
let data = list;

<img class="img-{{index}}" wx:for="{{data}}"></img>

data.forEach((item,index)=>{
    this.createIntersectionObserver().relativeToViewport.observe(`.img-${index}`,res=>{
        if (res.intersectionRatio > 0){
            this.setData({
                item.imgShow:true
            })
        }
    })
})

intersectionRatio值大于0,说明元素出现在视图中了,重新setData数据,显示图片组件。

实践技巧三

1

存在图片太大而显示区域过小

这个问题就是指图片尺寸太大了,而页面上我们显示的尺寸又太小了,图片尺寸大,请求图片就越慢,导致页面渲染速度下降。

2

CDN图片处理

对于页面里面的图片,最好都把图片存储在cdn服务器上,一个是能充分利用cdn缓存来加快请求速度,另外一个就是cdn上能够将图片进行一定的处理,比如裁剪。我司就是通过cdn来响应图片处理,然后请求图片时告诉cdn服务器需要什么要的尺寸图片,由cdn服务器响应对应尺寸图片。

实践技巧四

1

key值在列表渲染中的作用

key值在列表渲染的时候,能够提升列表渲染性能,为什么呢?首先得想想小程序的页面是如何渲染的,主要分为以下几步: ①将wxml结构的文档构建成一个vdom虚拟数 ②页面有新的交互,产生新的vdom数,然后与旧数进行比较,看哪里有变化了,做对应的修改(删除、移动、更新值)等操作 ③最后再将vdom渲染成真实的页面结构

key值的作用就在第二步,当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。

key值如果不指明,默认会按数组的索引来处理,因而会导致一些类似input等输入框组件的值出现混乱的问题。

原文作者:Rolan

原文地址:

http://www.wxapp-union.com/portal.php?mod=view&aid=5044

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯NEXT学院 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档