当前位置: 首页 > 知识库问答 >
问题:

VueJS、Vuetify、Data-Table-Expandable、性能问题

章稳
2023-03-14

我的VueJS和Vuetify项目有问题。我想创建一个包含可扩展行的表。这将是一个订单表,有可能看到购买的产品为每一个。对于一个页面,它应该显示至少100行订单。为此,我使用了Vuetify框架中的

准备好一切后,我意识到它可以工作,但是对于每一行的扩展,我必须等待几秒钟(太长了--它必须是一个快速的系统)。为了展开所有可见的记录,需要等待20秒以上,并且整个页面滞后。

我从标准的Vuetify 开始使用show-expand道具和expand-item插槽--这是我第一次尝试--速度最慢。其次,我尝试自己创作--但用Vuetify:

<v-data-table>
 <template v-slot:item="{item}">
   <td @click="item.expanded = !item.expanded">expand / hide</td>
   <!--- [my table content here - too long to post it here] -->
   <tr v-if="item.expanded">
     <td :colspan="headers.length">
     <v-data-table>
       <!--- [content of the nested table - also too long to post it here] -->
     </v-data-table>
   </tr>
 </template>
</v-data-table>

有趣的是--我意识到v-ifv-show工作得更快,这是一个奇怪的事实,因为我认为将display:none更改为nothing应该比向DOM中添加/删除整个对象的问题少。

这种方法比第一种方法快了一点,但还是太慢了。

我发现了一个提示,可以为表中的每个v-btn设置:ripple=“false”,我这样做了--有帮助,但只是一点点。所有的测试都在Chrome和Firefox,三台装有Windows和Linux的设备Fedora和两部android智能手机上进行。

不然我该怎么办?

提前谢谢!

共有1个答案

汪才英
2023-03-14

这篇优秀的文章建议DOM节点的原始数量对性能的影响最大。话虽如此,但我在为了解更多问题而构建的示例应用程序中并没有遇到任何真正的性能瓶颈。包含表的整个页面在大约1.25s(从localhost)中加载,而不管它是处于dev模式还是生产版本。JavaScript控制台计时器报告同时扩展或收缩所有100行平均只需0.3秒。总之,我认为您可以实现您想要的优化,而不必放弃Vuetify的便利性。

  1. 考虑一次显示较少的行(预期影响最大)
  2. 精简模板,使其使用的元素尽可能少,只显示用户真正需要的数据。您真的需要v-data-table内部的v-data-table吗?
  3. 简化数据模型,只检索显示表所需的最小数据。正如@codeply-er所建议的,数据的大小和复杂性可能导致这种压力

我是这么做的。我创建了一个简单的Vue/Vuetify应用程序,它带有一个vdataTable和100个可扩展行。(数据是从随机用户API中提取的)。我使用这种方法来计算DOM节点。以下是一些参数/信息:

  • 行:100
  • 列:5+展开切换器
  • 展开行内容:包含用户图片和地址的vSimpleTable
  • 从API返回的单个JSON记录的大小:~62行(大约是上面示例对象大小的一半)
  • VUE v2.6.11
  • Vuetify V2.3.0-beta.0
    (我知道这是刚刚发布的,但我认为使用V2.2.x不会有不同的结果)
  • 应用程序是用vue创建myappvue添加vuetify
  • 构建的
  • VDataTable实际上只要展开/收缩行,就会从DOM中添加/删除展开行

下面是关于结果的一些近似统计(这些数字在不同的条件下略有波动--YMMV):

  • 773(~7个/行):100行/5列中未启用扩展的DOM节点数
  • 977(+2/行):启用扩展的节点数
  • 24:通过展开单行而添加到表中的节点数
  • 3378(+26/行):已展开所有行的节点总数
  • ~1.25s硬刷新加载整个页面
  • ~0.3秒同时展开或收缩所有节点
  • 使用内置的排序工具对列进行排序是快速且非常有用的

下面是我的应用程序的app.vue页面的代码。v-data-table几乎是页面上唯一的组件(除了切换按钮),我没有导入任何外部组件。

<template>
  <v-app>
    <v-btn
      color="primary"
      @click="toggleExpansion"
    >
      Toggle Expand All
    </v-btn>
    <v-data-table
      :expanded.sync="expanded"
      :headers="headers"
      :items="items"
      item-key="login.uuid"
      :items-per-page="100"
      show-expand
    >
      <template #item.name="{ value: name }">
        {{ name.first }} {{ name.last }}
      </template>
      <template #expanded-item="{ headers, item: person }">
        <td :colspan="headers.length">
          <v-card
            class="ma-2"
            max-width="500px"
          >
            <v-row>
              <v-col cols="4">
                <v-img
                  :aspect-ratio="1"
                  contain
                  :src="person.picture.thumbnail"
                />
              </v-col>
              <v-col cols="8">
                <v-simple-table>
                  <template #default>
                    <tbody>
                      <tr>
                        <th>Name</th>
                        <td class="text-capitalize">
                          {{ person.name.title }}. {{ person.name.first }} {{ person.name.last }}
                        </td>
                      </tr>
                      <tr>
                        <th>Address</th>
                        <td class="text-capitalize">
                          {{ person.location.street.number }} {{ person.location.street.name }}<br>
                          {{ person.location.city }}, {{ person.location.state }} {{ person.location.postcode }}
                        </td>
                      </tr>
                      <tr>
                        <th>DOB</th>
                        <td>
                          {{ (new Date(person.dob.date)).toLocaleDateString() }} (age {{ person.dob.age }})
                        </td>
                      </tr>
                    </tbody>
                  </template>
                </v-simple-table>
              </v-col>
            </v-row>
          </v-card>
        </td>
      </template>
    </v-data-table>
  </v-app>
</template>

<script>
  import axios from 'axios'
  export default {
    name: 'App',
    data: () => ({
      expanded: [],
      headers: [
        { text: 'Name', value: 'name' },
        { text: 'Gender', value: 'gender' },
        { text: 'Phone', value: 'phone' },
        { text: 'Cell', value: 'cell' },
        { text: 'Country', value: 'nat' },
        { text: '', value: 'data-table-expand' },
      ],
      items: [],
    }),
    created () {
      axios.get('https://randomuser.me/api/?seed=stackoverflow&results=100')
        .then(response => {
          this.items = response.data.results
        })
    },
    methods: {
      toggleExpansion () {
        console.time('expansion toggle')
        this.expanded = this.expanded.length ? [] : this.items
        console.timeEnd('expansion toggle')
      },
    },
  }
</script>

您可以在此代码中看到一个工作演示。希望这有帮助!

 类似资料:
  • 实现类似腾讯爱看app的列表效果,点击列表任意一行,展开列表行,并最终成为主界面,显示列表行的详细内容。 [Code4App.com]

  • 这是我的应用程序组件: 我的应用程序从一个空数组开始,当我接收数据时,第一个容器从12的宽度缩小到9的宽度。代码本身运行良好,但是内部的图表会对视口中的变化做出反应,所以get的当前被切断了。一般来说,它看起来更好当这是动画。 有没有人知道我是否可以以及如何用过渡或其他动画来更改的宽度?

  • 我已经搜索了前面所有的问题,在Vuetify的新版本中,自定义的主题和图标对我来说都不起作用了。 vuetify.js文件: main.js文件: navbar.vue文件:(使用) 由于我的自定义主题,navbar的颜色应该是黑色,但它仍然是vuetify默认的蓝色。请指教。

  • fixed-data-table 是一个用于以灵活且强有力的方式建立并显示数据的 React 组件。它支持标准的桌面特征,像头条、行、列、头条组、滚动列。此组件在处理数千行数据的时不会牺牲性能。平滑地滚定是 FixedDataTable 的首要目的,它的结构保证了它的灵活性和可扩展性。 示例代码: var React = require('react');var FixedDataTable = 

  • Bootstrap Data Table 是 jQuery 表格插件,可以对表格进行排序,分页和过滤。Bootstrap Data Table 使用 Bootstrap 作为样式,使用 FontAwesome 图标作为表格图标。 在线演示

  • 我的应用程序在所有浏览器中工作,除了IE11。在IE中,我得到。我已经添加了babel polyfill,但我仍然得到相同的错误,就像polyfill没有正确编译。 我安装了babel-polyfill。 我更改了webpack.base.conf.js,如下所示 这个项目是从Vuetify的webpack样板开始的。