广告
返回顶部
首页 > 资讯 > 精选 >小程序列表懒加载如何实现
  • 546
分享到

小程序列表懒加载如何实现

2023-06-29 19:06:28 546人浏览 泡泡鱼
摘要

本文小编为大家详细介绍“小程序列表懒加载如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“小程序列表懒加载如何实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。小程序上的列表懒加载长列表我们经常接触到,长列

本文小编为大家详细介绍“小程序列表懒加载如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“小程序列表懒加载如何实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

    小程序上的列表懒加载

    长列表我们经常接触到,长列表为什么需要懒加载呢,因为一旦渲染内容多了,渲染引擎就需要更多的时间去渲染画面,这时可能会出现页面白屏、卡顿等。而用户其实只需要看到视窗内的内容就可以了,不用一次性把全部内容渲染完,所以可以通过懒加载实现。

    分页加载

    常见的列表懒加载是和后端一起实现,也就是分页加载。前端请求第几页的数据,后端就返回第几页的数据。前端要实现的交互就是当用户滑动到页面底部时,就要请求下一页的数据。

    用scroll事件监听

    小程序列表懒加载如何实现

    高度示意图

    监听scroll事件,事件回调会有当前元素的滚动距离scrollTop,当scrollTop+screenHeight等于滚动高度scrollHeight时,表示已经滑动到底部。

    在小程序中,Page对象提供onReachBottomapi

    onReachBottom: function() {  // 页面触底时执行},

    用IntersectionObserver监听

    用滚动监听会非常耗性能,滚动时频繁触发回调的,所以会不断去计算判断。比较好的优化方案是IntersectionObserverAPI,当IntersectionObserver监听的元素与可视区有相交状态时,就会产生回调,这样就减少了触发的频率

    Page({  onLoad: function(){    wx.createIntersectionObserver().relativeToViewport({bottom: 100}).observe('.target-class', (res) => {      res.intersectionRatio // 相交区域占目标节点的布局区域的比例,不等于0时表示有相交      res.intersectionRect // 相交区域      res.intersectionRect.left // 相交区域的左边界坐标      res.intersectionRect.top // 相交区域的上边界坐标      res.intersectionRect.width // 相交区域的宽度      res.intersectionRect.height // 相交区域的高度    })  }})

    前端分页渲染

    上面说的都是前端结合接口的分页加载。假如说接口没有分页,直接就返回了庞大的数据列表。前端如果直接就setData所有数据,会渲染很久,其实复杂的列表渲染20条的时候就已经很慢了。这个时候需要对已经获取到的数据进行分页,分批进行渲染。

    小程序列表懒加载如何实现

    通过右侧面板可以看到,一开始没有渲染所有节点,在滑动页面过程中节点再不断增加。

    直接上代码

    <!-- pages/first/index.wxml --><view class="container">  <block wx:for="{{GoodsList}}" wx:key="index" wx:for-item="subItemList">    <block wx:for="{{subItemList}}" wx:key="name">      <view class="item">{{item.name}}</view>    </block>  </block></view>

    goodsList是一个二维数组,用wx:for双重遍历

    // pages/first/index.jsconst list = Array.from({length: 5}, (item, index) => {  return Array.from({length: Math.ceil(Math.random()*10 + 5)}, (subItem, subIndex) => {    return {name: `第${index+1}屏, 第${subIndex+1}个`}  })})Page({  data: {    goodsList: [],    lazyloadIdx: 0  },  onLoad() {    this.setData({      goodsList: [list[0]],      lazyloadIdx: 1    })  },  // 滑动到底部时往goodsList添加数据  onReachBottom () {    console.log('onReachBottom');    let { lazyloadIdx } = this.data    if (lazyloadIdx >= list.length) return    this.setData({      [`goodsList[${lazyloadIdx}]`]: list[lazyloadIdx],      lazyloadIdx: lazyloadIdx+1    })  }})

    每次只setData一屏数据,既减少了setData数据量,又减少渲染时间

    用IntersectionObserver代替onReachBottom

    有很多场景用不了onReachBottom,那我们只能用IntersectionObserver代替。优化一下上面的代码

    # pages/second/index.wxml<view class="container">  <block wx:for="{{goodsList}}" wx:key="index" wx:for-item="subItemList">    <block wx:for="{{subItemList}}" wx:key="name">      <view class="item">{{item.name}}</view>    </block>  </block>+  <view id="observer" class="bottom"></view></view>

    增加节点用来监听

    //  pages/second/index.jslet lazyloadOb = nullPage({  data: {    goodsList: [],    lazyloadIdx: 0  },  onLoad() {    this.setData({      goodsList: [list[0]],      lazyloadIdx: 1    })    this.initObserver()  },  onunload () {    this.disconnenct()  },  lazyloadNext () {    console.log('lazyloadNext');    let { lazyloadIdx } = this.data    if (lazyloadIdx >= list.length) return    this.setData({      [`goodsList[${lazyloadIdx}]`]: list[lazyloadIdx],      lazyloadIdx: lazyloadIdx+1    })  },  initObserver () {    lazyloadOb = wx.createIntersectionObserver().relativeToViewport({ bottom: 50 }).observe('#observer', (res) => {      console.log('res.intersectionRatio', res.intersectionRatio);      // 触发回调时加载下一屏      if (res.intersectionRatio) this.lazyloadNext()    })  },  disconnenct() {    lazyloadOb.disconnenct()  }})

    加需求!

    后端返回的商品列表只是一个一维数组,需要前端转为二维数组,现在需要每屏的列表长度为5。

    假设商品列表个数为21,那么会生成二维数组对应的子项长度:

    // 伪代码[5, 5, 5, 5, 1]

    我们可以设定分页大小pageSize为5,当前分页pageNum,然后list.slice(pageNum, pageSize)就能截取对应的数据,再加入到二维数组中。

    但是产品来加需求了,商品列表默认只展示非售罄商品+一个售罄商品,其余售罄商品要点击【查看更多】按钮才展示

    假设非售罄商品有16个,售罄11个,每屏的列表长度还是5,那么:

    [  5, 5, 5,    // 非售罄  2,          // 非售罄+售罄  5, 5        // 售罄]

    只有两个的长度不大适合再分一屏,所以小于5时,直接跟前面的合并

    [  5, 5, 7, // 非售罄+一个售罄  5, 5     // 售罄]

    这个时候设定pageSize就没法满足了,所以要根据售罄个数,非售罄个数以及一屏长度,算出长度数组,再算出对应的二维数组

    genSubListSize (onSaleLen, soldOutLen) {  // 有售罄的时候,放一项售罄到非售罄那边去  if (soldOutLen) {    soldOutLen-= 1    onSaleLen+=1  }  const arr = []  const lazyloadListPartLength = 5 // 一屏5个  let firstSize = 0  if (onSaleLen < lazyloadListPartLength*2) {    firstSize = onSaleLen    onSaleLen = 0  } else {    firstSize = lazyloadListPartLength    onSaleLen -= lazyloadListPartLength  }  arr.push(firstSize)    // 子项长度  const size = lazyloadListPartLength  const remainder = onSaleLen % size  arr.push(    ...Array.from({length: Math.floor(onSaleLen/size) - 1}, () => size),  )  if (onSaleLen) {    arr.push(onSaleLen <= size ? onSaleLen : size + remainder)  }  // 记录此时售罄项的索引,因为要点击展开才能加载售罄列表  const soldOutIndex = arr.length  if (soldOutLen) {    const remainder = soldOutLen % size    arr.push(      ...Array.from({length: Math.floor(soldOutLen/size) - 1}, () => size),       soldOutLen <= size ? soldOutLen : size + remainder    )  }  console.log('genSubListSize', arr)    return {    subSize: arr,    soldOutLen,    soldOutIndex  }}

    现在取列表长度为20,12个非售罄,8个售罄,一屏5个

    // pages/third/indexconst goodsList = Array.from({length: 20}, (item, index) => {  return {name: `第${index+1}个`, soldOut: index < 12 ? false : true}})Page({  // ...  onLoad() {    this.initObserver()    this.handleGoodsList()  },  handleGoodsList () {    const { onSaleLen, soldOutLen } = this.countSaleLen()    console.log('onSaleLen', onSaleLen, 'soldOutLen', soldOutLen);    const {      subSize,      soldOutLen: soldOutLength,      soldOutIndex    } = this.genSubListSize(onSaleLen, soldOutLen)    const renderList = this.genRenderList(subSize)    console.log('renderList', renderList);  },  countSaleLen () {    const soldOutIndex = goodsList.findIndex(good => good.soldOut)    if (soldOutIndex === -1) {      return {        onSaleLen: goodsList.length,        soldOutLen: 0      }    }    return {      onSaleLen: soldOutIndex,      soldOutLen: goodsList.length - soldOutIndex    }  },  // 根据分组数组生成渲染列表  genRenderList (subSize) {    const before = goodsList    const after = []    let subList = [] // 二维数组子项    let subLen = 0 // 子项长度    let splitSizeArrIdx = 0 // 长度数组索引    for (let i = 0; i < before.length; i++) {      if (subLen === subSize[splitSizeArrIdx]) {        splitSizeArrIdx++        after.push(subList)        subList = []        subLen = 0      }      before[i]['part'] = `第${splitSizeArrIdx+1}屏`      subList.push(before[i])      subLen++    }    // 最后一个子项添加进去    after.push(subList)    return after  }})

    打印一下renderList,得到了动态切分的数据了

    小程序列表懒加载如何实现

    列表分组

    跑一下demo

    小程序列表懒加载如何实现

    当然需求是不断变化的,下次就不一定是售罄非售罄了,但是万变不离其宗,再怎么分,把每一项的数组长度定好之后,再生成渲染的renderList就可以了。所以可以把懒加载的这块逻辑抽离出来封装。

    读到这里,这篇“小程序列表懒加载如何实现”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网精选频道。

    --结束END--

    本文标题: 小程序列表懒加载如何实现

    本文链接: https://www.lsjlt.com/news/326193.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • 小程序列表懒加载如何实现
      本文小编为大家详细介绍“小程序列表懒加载如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“小程序列表懒加载如何实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。小程序上的列表懒加载长列表我们经常接触到,长列...
      99+
      2023-06-29
    • 小程序列表懒加载的实现方式
      目录小程序上的列表懒加载分页加载用scroll事件监听用IntersectionObserver监听前端分页渲染用IntersectionObserver代替onReachBotto...
      99+
      2022-11-13
    • 小程序如何实现图片懒加载方式
      这篇文章主要介绍了小程序如何实现图片懒加载方式,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。意义懒加载或者可以说是延迟加载,针对非首屏或者用...
      99+
      2022-10-19
    • 微信小程序图片懒加载如何实现
      这篇文章主要介绍“微信小程序图片懒加载如何实现”,在日常操作中,相信很多人在微信小程序图片懒加载如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”微信小程序图片懒加载如何实现”的疑惑有所帮助!接下来,请跟...
      99+
      2023-06-26
    • 小程序实现瀑布流动态加载列表
      本文实例为大家分享了小程序实现瀑布流动态加载列表的具体代码,供大家参考,具体内容如下 最近业务需要做一个商城列表,就自己写了一个瀑布流来加载列表。 这个列表在很多地方都需要用到,就...
      99+
      2022-11-13
    • 原生React怎么实现懒加载列表
      这篇文章主要介绍了原生React怎么实现懒加载列表的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇原生React怎么实现懒加载列表文章都会有所收获,下面我们一起来看看吧。应用场景懒加载列表或叫做无限滚动列表,也是...
      99+
      2023-07-05
    • 实现微信小程序中的图片懒加载效果
      实现微信小程序中的图片懒加载效果,需要具体代码示例随着移动互联网的快速发展,微信小程序已经成为了人们生活中不可或缺的一部分。而在开发微信小程序时,图片懒加载是一个常见的需求,可以有效地提升小程序的加载速度和用户体验。本文将介绍如何在微信小程...
      99+
      2023-11-21
      微信小程序 实现 图片懒加载
    • 微信小程序如何实现列表上拉加载下拉刷新功能
      这篇文章给大家分享的是有关微信小程序如何实现列表上拉加载下拉刷新功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1.列表(本部分内容出入官方文档)对于这个功能,微信小程序中并没...
      99+
      2022-10-19
    • 原生+React实现懒加载(无限滚动)列表方式
      目录应用场景效果预览思路剖析原生代码实现迁移到React总结应用场景 懒加载列表或叫做无限滚动列表,也是一种性能优化的方式,其可疑不必一次性请求所有数据,可以看做是分页的另一种实现形...
      99+
      2023-03-24
      React懒加载 React无限滚动 React列表
    • MyBatis懒加载如何实现
      这篇文章主要介绍“MyBatis懒加载如何实现”,在日常操作中,相信很多人在MyBatis懒加载如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MyBatis懒加载如何实现”的疑惑有所帮助!接下来,请跟...
      99+
      2023-06-30
    • webpack如何实现懒加载和预加载
      小编给大家分享一下webpack如何实现懒加载和预加载,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!正常加载为了看的方便,index.js中的代码非常简单console.log('index.js执行了')...
      99+
      2023-06-22
    • 小程序如何实现图片预加载
      这篇文章主要为大家展示了“小程序如何实现图片预加载”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“小程序如何实现图片预加载”这篇文章吧。    网页有页面预加载,小程序也有图片预加载,小程序图片加...
      99+
      2023-06-26
    • android fragment懒加载如何实现
      Android Fragment的懒加载可以通过以下步骤实现:1. 在Fragment类中添加一个boolean类型的变量isLoa...
      99+
      2023-08-26
      android fragment
    • 微信小程序如何实现下拉列表
      这篇文章给大家分享的是有关微信小程序如何实现下拉列表的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。微信小程序 下拉列表wxml代码: <view cla...
      99+
      2022-10-19
    • 微信小程序如何实现城市列表
      小编给大家分享一下微信小程序如何实现城市列表,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!picker-view嵌入页面的滚动选择器注意:其中只可放置组件,其他节...
      99+
      2023-06-26
    • 微信小程序如何实现虚拟列表
      这篇文章给大家分享的是有关微信小程序如何实现虚拟列表的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言大部分小程序都会有这样的需求,页面有长列表,需要下拉到底时请求后台数据,一直渲染数据,当数据列表长时,会发现明...
      99+
      2023-06-20
    • vue如何实现一个懒加载的树状表格
      这篇文章主要介绍“vue如何实现一个懒加载的树状表格”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vue如何实现一个懒加载的树状表格”文章能帮助大家解决问题。一个懒加载的树状表格实例实现一个树状表格...
      99+
      2023-06-30
    • 如何通过IntersectionObserver实现懒加载
      通常懒加载等都会通过监听scroll事件用getBoundingClientRect()来判断元素位置来决定是否可以开始加载。性能开销是比较大的,为了节省性能又需要各种操作去弥补,例...
      99+
      2023-05-16
      IntersectionObserver懒加载
    • vue2组件如何实现懒加载
      这篇文章给大家分享的是有关vue2组件如何实现懒加载的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、 什么是懒加载懒加载也叫延迟加载,即在需要的时候进行加载,随用随载。二、为什...
      99+
      2022-10-19
    • vue如何实现路由懒加载
      在vue中实现路由懒加载的方法有:1.使用import方法实现;2.使用require.ensure()方法实现;3.使用vue异步组件实现;具体方法如下:使用import方法实现路由懒加载const Home = () => import...
      99+
      2022-10-20
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作