微信小程序长列表优化方案

原文链接:https://www.cnblogs.com/plBlog/p/12053973.html

案例代码片段:https://gitee.com/huang_ting/group-list-optimization


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

复制代码
<!--只阐述逻辑,非真实代码-->// 1: 初始一个list,存储列表数据
data = startList
// 2: 监听滚动事件,滚动到底部获取新数据,并追加到list尾部,最后重新setData
onReachBottom:()=>{const {list} = this.datafetchNewData().then((res)=>{list.push(res.list);this.setData({list})}
}

我估计大部分人面对长列表滚动的时候,一开始的处理方式都是这样的,如果数据不多,只有几页可能不会太暴露问题,如果页数过多,几十页甚至上百页的情况,list的数据会越来越大,每次setData的数据就会越来越多,因而每次页面重新渲染的节点就会越来越多,从而导致滚动到后面,加载越来越慢。另外,由于小程序的视图渲染层和数据逻辑处理层是分开的,不是在同一个线程上面的,从用户触发页面交互,到处理数据逻辑,最后层现页面,数据到视图是需要传输的,因而小程序本身对数据大小也有限制,不能超过1M。

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

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

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

// 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遍历渲染数据

存在短时间内发起太多图片请求(图片懒加载)

这个应该好理解,就是渲染页面时,一次性发送了过多的图片请求,导致了同一时间发起了过多的http请求,http连接是非常耗时的,尤其是一次性发起这么多,并且一次性发起的http链接也是有限制的,比如chrome浏览器就限制一次性最多6个。

所以在渲染页面时,不在视图范围内的图片我们不加载,只有元素出现在视图范围内了,再渲染。

常规的做法是,通过getBoundingClientRect()获取元素的位置,然后与页面滚动位置比较,如果出现在视图内,就将img显示。这种方式有2个问题

getBoundingClientRect()方法调用本身容易引起页面重排
监听滚动事件本身就频繁触发,虽然可以通过节流的方式来减少,但还是容易增加无谓代码处理
IntersectionObserver
其实,微信提供了IntersectionObserver对象。

IntersectionObserver 对象,用于推断某些节点是否可以被用户看见、有多大比例可以被用户看见

通过这个api我们不用再主动去监听元素位置了,在页面渲染一开始,通过这个api指明需要监听的元素,系统会自动去监听了元素位置。

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数据,显示图片组件。

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

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

CDN图片处理

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

key值在列表渲染中的作用

key值在列表渲染的时候,能够提升列表渲染性能,为什么呢?首先得想想小程序的页面是如何渲染的,主要分为以下几步:

将wxml结构的文档构建成一个vdom虚拟数
页面有新的交互,产生新的vdom数,然后与旧数进行比较,看哪里有变化了,做对应的修改(删除、移动、更新值)等操作
最后再将vdom渲染成真实的页面结构
key值的作用就在第二步,当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。

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

不加key,在数组末尾追加元素,之前已渲染的元素不会重新渲染。但如果是在头部或者中间插入元素,整个list被删除重新渲染,且input组件的值还出现了混乱,值没有正常被更新
添加key,在数组末尾、中间、或者头部插入元素,其它已存在的元素都不会被重新渲染,值也能正常被更新

因而,在做list渲染时,如果list的顺序发生变化时,最好增加key,且不要简单的使用数组索引当做key。

微信小程序长列表优化方案相关推荐

  1. 微信小程序 — 长列表组件 recycle-view 详细教学

    微信小程序 - 长列表组件 recycle-view 踩坑问题全解 写在前面 引入长列表组件 recycle-view 长列表组件 recycle-view 的使用 问题一.如何增加下拉刷新功能? 问 ...

  2. 判断 小程序 是否 滚动到页面底部 scrolltolower_微信小程序长列表性能优化——recycle-view

    背景: 第七次人口普查项目使用是微信小程序原生框架,组件是根据用户需求由项目组前端组组长封装完成的.采集小程序正式登记首页列表页面,根据腾讯老哥在sentry上的监控可以看出,列表页面前端性能比较差, ...

  3. 微信小程序长列表 数据渲染的些许优化

    开始写长列表的时候,是将分页数据合并到一起在重新渲染,发现正常浏览还行,但是数据超过200多条的时候,新数据会出现一段白屏时间.于是做了如下些许优化 var datalistt = res.datav ...

  4. 微信小程序新闻列表详情页

    微信小程序新闻列表详情页 不忘初心,方得始终.初心易得,始终难守 首先创建 post-detail 文件夹,创建四种文件. 修改 post.wxml 文件代码,给每个新闻块添加一个点击事件.并且我们要 ...

  5. 微信小程序长按识别二维码,小程序相关问题总结

    微信小程序长按识别二维码,小程序相关问题总结 开发小程序中,长按识别二维码,小程序码跳转,已知问题整理: 小程序中,不支持长按识别二维码,和小程序码. 可利用小程序 图片预览功能识别 小程序码并进行跳 ...

  6. 微信小程序新闻列表功能(读取文件、template)

    微信小程序新闻列表功能(读取文件.template) 在之前的项目基础上进行修改,实现读取文件内容作为新闻内容进行展示. 首先,修改 post.wxml 文件,和 post.js 文件中,某些键值对键 ...

  7. 微信小程序长按保存图片

    微信小程序长按保存图片 wxml部分 <image data-url="{{item}}" bindlongtap="longPressSaveImg " ...

  8. 微信小程序多级列表绑定

    微信小程序多级列表绑定 1.wxml <view class="weui-form-preview margin-bottom" wx:key="" wx ...

  9. 微信小程序C语言通讯录,微信小程序のwxml列表渲染

    列表渲染存在的意义 以电商为例,我们希望渲染5个商品,而又希望容易改变,我们就要在wxml中动态添加. {{index+1}}:{{item.name}} Page({ data: { message ...

  10. 微信小程序长按图片发送给好友

    问题描述 微信小程序长按图片发送给好友 解决方法 直接在<image></image>标签添加:show-menu-by-longpress="true" ...

最新文章

  1. 想不到,那些让我半夜偷偷收藏的沙雕表情包,竟是出自 AI 之手
  2. 有趣的Pycharm第三方模块——为正在学习python的可怜孩子找点乐趣
  3. python怎么变白-python – 在热图中使反向对角线变白
  4. hiho #1044 : 状态压缩·一
  5. SpringBoot中使用fastjson将map转换成json
  6. VisualVM:通过SSH监视远程JVM(是否为JMX)
  7. 【Java线程】“打工人”初识线程池及自定义线程池实战
  8. linux系列之-—01 shell编程笔记
  9. ubuntu 12.04 以固定 IP 地址连接网络并配置DNS
  10. Linux 内存子系统常见参数以及调优
  11. 计算机键盘上的每一个按键编码,键盘按键修理
  12. 【长期维护】程序员锻炼法则
  13. 计蒜客-天上的星星(矩阵容斥)
  14. 一位清华差生9年的北京生活
  15. 什么是stub文件_stub code
  16. Dubbo原理简单分析
  17. SDOI 2009 学校食堂
  18. APISpace 行驶证OCR 方便好用
  19. Ubuntu14.04配置TFTP服务器
  20. Unity之Shader Pass 通道显示贴图的几种方法- 六

热门文章

  1. 151只宝可梦(神奇宝贝)倒背的我,却连元素周期表都背不过 -- Python 爬虫小课 3-9
  2. Python大作业-爬取成都链家租房信息(大作业)源码
  3. 基于第三方QQ授权登录
  4. 基于ROS的机器人设计
  5. 最近火爆全网的猫猫回收站教程,小七给你们搞来了
  6. android自动亮度流程,Android 亮度自动调节是如何实现的?
  7. 详解 python 的 切片
  8. 微纳自组装技术——纳米孔道阵列辅助自组装技术简述
  9. 从低位开始取出长整型变量s中奇数位上的数依次构成一个新数放在t中
  10. 自动化信任和依赖对航空安全的危害及其改进