【问题标题】:V-for with 3000+ recs loading REALLY slow (12+ seconds)V-for 3000+ 记录加载真的很慢(12+ 秒)
【发布时间】:2019-10-17 23:16:26
【问题描述】:

我有一个包含大约 3000 个对象(来自 Web 服务)的数组,我正在使用 v-for 呈现这些对象。

我的数组看起来像:

this.oParts = [
 {
 descript: 'my descript',
 partno: '1234567890123',
 partsid: '1234567890'
 partscatid: '1234567890',
 partscat2id: '1234567890'
 serialized: true,
 category: 'test',
 subcat: 'test-2'
 uofm: ''
 },
.
.
.3000 times
]

为了渲染,我使用 vuetifyjs:

<v-container>
   <v-row v-for="(x, index) in oParts" :key="index">
     <v-col>
      <!-- v-model.lazy="x.selected" -->
            <v-checkbox
                  value="false"
                  :label="x.descript + ' (' + x.partno + ')'"
                   :messages="x.partsid + (x.serialized ? ' (serialized)' : '')"
                    class="notes-chkBox"
                    color="primary"
                    @click.capture.stop="btnOKClicked(x)"
                    >
                    </v-checkbox>
              </v-col>
          </v-row>
</v-container>

加载时间超过 12 秒。我正在使用 Vue.js 2.6.10 版和 vuetify.js 2.0.15 版

我尝试过使用 v-once 并且 Object.freeze() 提到了here,但这似乎没有帮助。我在这里并不需要 2 路数据绑定。有没有其他方法可以加快这个列表的渲染速度?

【问题讨论】:

  • 几个想法/cmets。首先,您是否知道所有(大部分)延迟都是渲染而不是返回响应时的​​网络延迟?可能是这样,但值得检查以确保您没有尝试优化错误的东西。第二,你真的需要展示 3000 个项目吗?似乎这对用户来说可能是压倒性的。你能摆脱分页吗?你也可以看看 virtual-repeaters/virtual-scrollers
  • @StephenThomas 是的,我已经排除了网络。不,我不必一次显示 3000 个项目(虽然页面不是一个真正的选项)。基本上,有 3000 个部分可供选择,他们可以滚动到某个部分(如果它在字母表中足够低,或者我有一些过滤器可以输入,直到列表足够小,他们可以滚动并找到他们想要的部分. 我会研究一下虚拟卷轴。谢谢
  • 我自己尝试运行它,看到类似的渲染时间,大约 12 秒。每行向 DOM 贡献 13 个元素,因此使用 3000 行,您将拥有近 40000 个元素。虽然 12 中的大多数似乎确实是 Vue 创建组件、VNode 等,但也有相当大的浏览器样式计算和布局内容。即使您可以使用诡计来跳过 Vue 增加的开销,您也将难以通过如此多的元素保持快速的用户交互。底线是你需要找到一些方法来避免一次渲染这么多东西。

标签: vue.js vuejs2 vuetify.js


【解决方案1】:

看起来使用虚拟滚动条是要走的路。我发现这个是为 Vue.js 设计的,它从 12 秒到几乎瞬间完成。

https://github.com/Akryum/vue-virtual-scroller

新的html:

<v-container>
<RecycleScroller
   class="scroller"
   :items="oParts"
   :item-size="65"
   key-field="partsid"
   v-slot="{ item }"
   >
   <v-row>
      <v-col>
         <v-checkbox
            value="false"
            :label="item.descript + ' (' + item.partno + ')'"
            :messages="item.partsid + (item.serialized ? ' (serialized)' : '')"
            class="notes-chkBox"
            color="primary"
            @click.capture.stop="btnOKClicked(item)"
            >
         </v-checkbox>
      </v-col>
   </v-row>
</RecycleScroller>  
</v-container>     

【讨论】:

    猜你喜欢
    • 2012-09-17
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    • 2020-03-11
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    相关资源
    最近更新 更多