You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue JS 循环渲染大量商品项的性能优化技术咨询

核心问题原因

你遇到的卡顿本质是无限滚动加载后DOM节点和Vue组件实例大量堆积:加载1250件商品就意味着同时存在1250个商品组件实例和对应DOM节点,Vue需要维护所有组件的响应式绑定,路由切换时要批量销毁上千个节点和实例,这就是4-6秒延迟的核心来源。

优化方案

1. 优先使用虚拟列表(收益最高)

这是大列表场景的标准解决方案,无论总数据量多大,始终只渲染可视区域上下2-3屏的DOM节点,滚动时复用现有DOM替换内容,不会出现DOM堆积问题。

  • Vue2项目可以用vue-virtual-scroller组件,Vue3项目可以用vueuse提供的useVirtualList工具,也可以直接用UI组件库自带的虚拟列表组件
  • 改造成本极低:仅需要把现有v-for的部分替换为虚拟列表组件,传入全量商品数据、配置每一项的固定高度、复用你现有的item-card/item-card-for-mobile组件作为渲染模板即可,原有业务逻辑完全不用修改

2. 现有无限滚动加DOM卸载逻辑(过渡方案)

如果暂时不想重构为虚拟列表,可以给现有滚动逻辑加不可见区域DOM卸载规则,把DOM数量控制在百级以内:

  • 把商品按每30件分为一组,给每组加可见性监听(可以直接复用你现有的vue-observe-visibility能力)
  • 不在可视区域上下2屏范围内的分组直接用v-if=false卸载DOM,仅保留商品数据在内存中,需要展示时再重新渲染

3. 现有代码细节优化

不需要改核心逻辑的前提下,做以下优化也能大幅降低性能开销:

  • 把设备类型判断移到v-for外层,避免循环内每一项都重复判断mobile变量,优化后代码示例:
<template v-if="!mobile">
  <div v-for="value in filteredRecords.slice(0, showCount)" :key="value.id">
    <item-card 
      :product_id="value.id" 
      :product_slug="value.product_slug"
      :product_name="value.product_name"
      :product_img="getImage(value.product_img , '300x300')" 
      :product_price="value.product_price" 
      :product_sale_price="value.product_sale_price"
      :product_stock="value.product_stock"
      :locale="locale" 
      :heart="true"
    />
  </div>
</template>
<template v-else>
  <div v-for="value in filteredRecords.slice(0, showCount)" :key="value.id">
    <item-card-for-mobile
      :product_id="value.id" 
      :product_slug="value.product_slug"
      :product_name="value.product_name"
      :product_img="getImage(value.product_img , '300x300')" 
      :product_price="value.product_price" 
      :product_sale_price="value.product_sale_price"
      :product_stock="value.product_stock"
      :locale="locale" 
      :quickview="true"
    />
  </div>
</template>
  • 给getImage函数加缓存,相同入参直接返回结果,避免每次渲染都重复计算
  • 开启商品图片懒加载,仅加载可视区域内的图片,降低内存占用
  • Vue2可以把商品组件改为函数式组件,Vue3可以用markRaw包裹不需要响应式的商品属性、或者给组件开启shallow模式,减少响应式绑定开销

4. 路由切换优化

如果做完上述优化还有延迟,可以加主动清屏逻辑:

  • 监听路由离开钩子,离开列表页前先把整个商品列表容器的v-if设为false,主动清空所有商品DOM后再执行路由跳转,配合简单的loading过渡动画即可完全隐藏销毁耗时

内容的提问来源于stack exchange,提问作者rocket_moon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 04:48:03