uni-app nvue concat追加数据过多时,更改数据内容出现卡屏停顿后才更新数据

uni-app nvue concat追加数据过多时,更改数据内容出现卡屏停顿后才更新数据

测试过的手机:

  • iphone 11 pro
  • iphone 12 mini
  • 华为mete30

示例代码:

<!-- #ifdef H5 -->
<scroll-view :scroll-top="goodsScrollTop" class="u-p-t-20 u-p-b-20 flex bgWhite scroll_column" scroll-y :style="{height:(pageHeight-botHeight-safeArea.top-safeBottomHeiVal)+'px'}" :scroll-with-animation='true' @scroll="scroll">
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<list ref="list" @loadmore="loadmore" loadmoreoffset='10' :show-scrollbar="false" fixFreezing="true" class="u-p-t-20 u-p-b-20 flex bgWhite" :style="{height:(pageHeight-botHeight-safeArea.top)+'px'}">
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<cell v-if="list.length" v-for="(item,index) in list" :key="index" class="u-p-l-30 bgWhite">
<!-- #endif -->
<!-- #ifdef H5 -->
<view v-if="list.length" v-for="(item,index) in list" :key="index" class="u-p-l-30 bgWhite">
<!-- #endif -->
<goodsItem :item2="item" :isdel="true" :isforcart="isforcart" :index='index' @getshow="getshow" @getlinkGoods="getlinkGoods" @refresh="refresh" :isRecShort="true" @getinfo="getinfo" @getbtnType='getbtnType'></goodsItem>
<!-- #ifdef H5 -->
</view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
</cell>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<cell ref="top">
<!-- #endif -->
<nodata v-if="list.length===0" :isBack="true" buttonText="去逛逛"></nodata>
<!-- #ifdef APP-PLUS -->
</cell>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
</list>
<!-- #endif -->
<!-- #ifdef H5 -->
</scroll-view>
<!-- #endif -->

操作步骤:

  • 页面中有两个分类元素。 默认 nvue 写一个列表 list 循环cell 组件 渲染出第一个列表。 loadmore的时候 不断去concat新的数据,一直loadmore。再次请求第二个分类元素 触发把list的循环数据置为空
  • 应用商城搜索《冻品到家》点击。常购清单 切换 左侧分类

预期结果:

  • 数据即时切换为新的数据

实际结果:

  • 实际的效果如下:切换数据页面卡顿。具体是:清除当前屏幕显示的数据之后,页面之外的数据展现出来 清除清楚当前数据。 直到页面中的旧数据清理完毕。 再一次性展现出来 新的数据

bug描述:

  • list包含循环cell元素,数据比较长的时候再去切换数据,出现明显卡顿,明显的回收旧数据的过程,数据列表长度越长卡顿的时间就越长,随后才渲染新的数据

更多关于uni-app nvue concat追加数据过多时,更改数据内容出现卡屏停顿后才更新数据的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

请求官方重视,当前app 影响正常使用

更多关于uni-app nvue concat追加数据过多时,更改数据内容出现卡屏停顿后才更新数据的实战教程也可以访问 https://www.itying.com/category-93-b0.html


在nvue中,当list组件包含大量数据时,直接清空并重新赋值大量数据确实可能导致卡顿。这是因为nvue的list组件基于原生渲染,数据更新涉及原生组件的重新渲染和回收过程。

主要问题在于:

  1. 原生渲染开销:nvue的list和cell基于原生列表组件(iOS为UITableView,Android为RecyclerView),大量数据的清除和重新渲染会触发原生的布局和渲染计算。
  2. 数据更新方式:直接置空list再赋新值,会触发完整的列表刷新,而非增量更新。

建议优化方案:

  1. 使用recycle-list替代list(如果适用):

    <recycle-list :list="listData" template-key="id">
      <cell-slot template-type="item" :data="item">
        <!-- 内容 -->
      </cell-slot>
    </recycle-list>
    

    recycle-list针对长列表有更好的性能优化。

  2. 分页加载时避免concat: 改为直接替换数组而非合并:

    // 替换
    this.list = newDataArray;
    // 而非
    this.list = this.list.concat(newDataArray);
    
  3. 切换分类时使用v-if控制显示: 为不同分类维护独立的数据数组,通过v-if切换显示,避免频繁清空和重赋大数据:

    <list v-if="currentTab === 'tab1'" :data="list1">
      <!-- ... -->
    </list>
    <list v-else :data="list2">
      <!-- ... -->
    </list>
    
  4. 使用key属性优化复用: 为cell设置稳定的key值,帮助原生组件更好地复用:

    <cell v-for="item in list" :key="item.id">
      <!-- ... -->
    </cell>
    
  5. 考虑分片更新: 对于极大数据量,可以分批更新:

    // 示例
    this.list = [];
    setTimeout(() => {
      this.list = newData;
    }, 50);
回到顶部