• 小程序 scroll-view 性能问题


    先说使用场景,一次加载很多数据造成小程序卡顿的问题 ,找了好多都没有好的解决办法,要么太过复杂,然后研究了两天通过简单的办法实现,先根据数量把高度撑开,然后根据滚动位置渲染指定的数据就可以了, 性能简直不要太好。先看效果(实际业务效果要好于测试效果)。

    小程序列表性能

    DataManage.js  封装

    1. function DataManage() {
    2. //**********************************************************数据
    3. let Data = {
    4. dataSource: [],//数据源
    5. heatData: [] //热数据(需要渲染的数据)
    6. }
    7. //**********************************************************配置
    8. let BaseConfig = { //基本配置信息(不需要覆盖的配置)
    9. triggerTime: 0, //滚动时间
    10. triggerTop: 0, //滚动top位置
    11. voidViewHeight: 0,//虚拟View高度
    12. pagingIndex: -1, //切换分页索引
    13. dataEnd: -1 //数据结束范围
    14. }
    15. let PagingConfig = { //分页配置(可改变)
    16. pageSize: 50, //分页大小
    17. cardHeight: 55, //卡片高度
    18. pagingBoundary: 20,//切换数据边界值(此值需要小于分页大小)
    19. topBoundary: 20, //数据上移边界
    20. callback: '',//回调方法
    21. debug: false //输出日志
    22. }
    23. let CallbackFn = null //回调方法
    24. //**********************************************************内部方法
    25. const refreshData = (viewData) => {//刷新数据
    26. Data.heatData = viewData.viewList
    27. CallbackFn(viewData)
    28. }
    29. const virtualPaging = () => {//虚拟分页
    30. if (Data.dataSource.length <= PagingConfig.pageSize) {//不分页处理
    31. refreshData({ viewList: Data.dataSource, voidViewHeight: BaseConfig.voidViewHeight, viewListTop: 0 })
    32. return;
    33. }
    34. let currentIndex = Math.floor(BaseConfig.triggerTop / PagingConfig.cardHeight)//根据位置计算当前索引值
    35. if (BaseConfig.pagingIndex == -1 || (currentIndex != BaseConfig.pagingIndex && Math.abs(currentIndex - BaseConfig.pagingIndex) >= PagingConfig.pagingBoundary)) {
    36. //数据范围
    37. let dataS = currentIndex - PagingConfig.topBoundary < 0 ? 0 : currentIndex - PagingConfig.topBoundary//起始位置
    38. let dataE = dataS + PagingConfig.pageSize//结束位置
    39. if (Math.abs(Data.dataSource.length - dataE) <= PagingConfig.pagingBoundary)//避免丢失最后的数据
    40. dataE = Data.dataSource.length
    41. if (dataE == BaseConfig.dataEnd)//避免总数据量只大于分页数造成的多一次渲染
    42. return;//返回后,此处会触发多次,因为下面的变量没有更新
    43. //刷新数据
    44. refreshData({
    45. viewList: Data.dataSource.slice(dataS, dataE),
    46. voidViewHeight: BaseConfig.voidViewHeight,
    47. viewListTop: dataS * PagingConfig.cardHeight
    48. })
    49. //保存此次分页位置
    50. BaseConfig.dataEnd = dataE
    51. BaseConfig.pagingIndex = currentIndex
    52. //打印日志
    53. if (PagingConfig.debug)
    54. console.log("虚拟分页,位置索引->", currentIndex, "上次分页索引->", BaseConfig.pagingIndex, "数据范围[" + dataS + "-" + dataE + "]")
    55. }
    56. }
    57. //**********************************************************对外方法
    58. /**
    59. * 初始化
    60. */
    61. const Init = (_pagingConfig, _data, _callback) => {
    62. PagingConfig = { ...PagingConfig, ..._pagingConfig }
    63. Data.dataSource = _data
    64. CallbackFn = _callback
    65. BaseConfig = {
    66. triggerTime: 0,
    67. triggerTop: 0,
    68. voidViewHeight: _data.length * PagingConfig.cardHeight,
    69. pagingIndex: -1,
    70. dataEnd: -1
    71. }
    72. virtualPaging()
    73. }
    74. /**
    75. * scroll-view 滚动事件
    76. */
    77. const RollEvent = (e) => {
    78. if (Data.dataSource.length <= PagingConfig.pageSize)
    79. return;
    80. BaseConfig.triggerTime = new Date().getTime()
    81. BaseConfig.triggerTop = e.detail.scrollTop
    82. virtualPaging()
    83. }
    84. return {
    85. Init, RollEvent
    86. }
    87. }
    88. export {
    89. DataManage as dm
    90. }

    test1.js调用

    1. import { dm } from "../../utils/DataManage"
    2. const DM = dm()
    3. Page({
    4. /**
    5. * 页面的初始数据
    6. */
    7. data: {
    8. TestAllData: [],//为了测试位置 对齐
    9. voidViewHeight: 0,//虚拟列表高度
    10. viewListTop: 0, //数据列表Top起始位置
    11. viewList: [], //显示的数据
    12. },
    13. rollEvent(e) {//滚动事件
    14. DM.RollEvent(e)
    15. },
    16. /**
    17. * 生命周期函数--监听页面加载
    18. */
    19. onLoad(options) {
    20. let DataSource = []
    21. for (var i = 0; i < 10000; i++) {
    22. DataSource.push({ sn: i, text: "第" + i + "个订单" })
    23. }
    24. this.setData({ TestAllData: DataSource })
    25. DM.Init({ debug: true }, DataSource, (data) => { this.setData(data)})
    26. }
    27. })

     test1.wxml 布局

    1. <view class="container">
    2. <view style="position: fixed; top: 0; background-color: blueviolet; width: 100%; height: 25px; z-index: 999; ">
    3. <navigator url="/pages/order/order">订单navigator>
    4. view>
    5. <view style="margin-top:25px ; ">
    6. <scroll-view enhanced scroll-y bindscroll="rollEvent" style="height: calc(100vh - 25px);">
    7. <view class="voidView" style="height:{{voidViewHeight}}px;">
    8. <view style=" height: 55px; align-content: center; color: greenyellow;" wx:for="{{TestAllData}}" wx:key="sn">
    9. {{item.sn }}view>
    10. view>
    11. <view class="dataView" style="top:{{viewListTop<0?0:viewListTop}}px">
    12. <view class="orderCard" wx:for="{{viewList}}" wx:key="sn">
    13. {{item.sn }} - {{item.text}}
    14. view>
    15. view>
    16. scroll-view>
    17. view>
    18. view>

    test1.wxss  样式

    1. ::-webkit-scrollbar {
    2. width: 0;
    3. height: 0;
    4. color: transparent;
    5. }
    6. /* 占位元素 */
    7. .voidView {
    8. position: absolute;
    9. width: 30px;
    10. background-image: url('http://192.168.1.8:808/images/back.png');
    11. }
    12. /* 列表容器 */
    13. .dataView {
    14. width: 100vw;
    15. padding-left: 30px;
    16. position: absolute;
    17. }
    18. /* 订单卡片 */
    19. .orderCard {
    20. height: 50px;
    21. background-color: coral;
    22. margin: 5px 5px 5px 5px;
    23. text-align: center;
    24. font-size: 24px;
    25. }

  • 相关阅读:
    重定向与转发的几种方式
    Protobuf的简单使用
    记一次问题排查
    神经网络模型如何使用的,神经网络模型是干嘛的
    【老生谈算法】matlab实现遗传算法在调节控制系统参数中的应用——遗传算法
    c语言分层理解(c语言文件操作)
    【Python黑科技】制作一个定时小闹钟,自动发送系统通知提示(保姆级图文+实现代码)
    Node版本管理工具——Nvm
    Node.js开发-fs模块
    【JS】js数字转k、w结尾 | 1000 = 1k
  • 原文地址:https://blog.csdn.net/w13511069150/article/details/134240167