[英]VueJS, Vuetify, data-table - expandable, performance problem
I've got a problem with my VueJS and Vuetify project.我的 VueJS 和 Vuetify 项目有问题。 I wanna create a table with expandable rows.
我想创建一个带有可扩展行的表。 It'll be a table of orders with possibility to see bought products for each one.
这将是一张订单表,可以查看每个订单的购买产品。 For one page it should show at least 100 rows of orders.
对于一页,它应该显示至少 100 行订单。 For this, I used
<v-data-table>
from the Vuetify framework.为此,我使用了 Vuetify 框架
<v-data-table>
。
After preparing everything I realized that it works, but for expansion for each row, I have to wait a few seconds (it's too long - it must be a fast system).在准备好一切之后,我意识到它可以工作,但是对于每一行的扩展,我必须等待几秒钟(它太长了 - 它必须是一个快速的系统)。 And for expanding all visible records it is necessary to wait more than 20 seconds with whole page lag.
并且为了扩展所有可见记录,需要等待超过20 秒的整页延迟。
I started with standard Vuetify <v-data-table>
with a show-expand
prop and with an expanded-item
slot - it was my first try - the slowliest.我从标准的 Vuetify
<v-data-table>
开始,带有一个show-expand
道具和一个 expand expanded-item
插槽 - 这是我的第一次尝试 - 最慢。 Secondly, I tried to create on my own - but with Vuetify:其次,我尝试自己创建 - 但使用 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>
What's interesting - I realized that v-if
works faster than v-show
, which is a weird fact, because I thought that changing display: none
to nothing should be less problematic than adding/removing whole objects to DOM.有趣的是 - 我意识到
v-if
比v-show
工作得更快,这是一个奇怪的事实,因为我认为将display: none
更改为 none 应该比将整个对象添加/删除到 DOM 问题更小。
This method was a little faster than first, but it is still too slow.这种方法比第一种方法快一点,但还是太慢了。
I found a hint to set :ripple="false"
for every v-btn
in my tables and I did it - helped, but only a bit.我找到了一个提示,为我的表中的每个
v-btn
设置:ripple="false"
并且我做到了 - 有所帮助,但只有一点点。 Everything was tested on Chrome and Firefox, on three devices with Windows and Linux Fedora and two android smartphones.一切都在 Chrome 和 Firefox、Windows 和 Linux Fedora 和两部 ZC31B32364CE19CA8ZFCD1 智能手机的三台设备上进行了测试。
What should else I do?我还应该怎么做?
Thank you in advance!先感谢您!
This excellent article suggests that the raw number of DOM nodes has the biggest impact on performance . 这篇优秀的文章表明 DOM 节点的原始数量对性能的影响最大。 That said, I didn't experience any real performance bottlenecks in the sample app that I built to learn more about your problem.
也就是说,在我构建的示例应用程序中,我没有遇到任何真正的性能瓶颈,以了解有关您的问题的更多信息。 The entire page with the table loaded in about 1.25s (from localhost), regardless of whether it was in dev mode or it was a production build.
包含表格的整个页面在大约 1.25 秒内加载(来自本地主机),无论它是处于开发模式还是生产版本。 The JavaScriptconsole timer reported that expanding or contracting ALL 100 rows simultaneously only took an average of about 0.3s.
JavaScript控制台计时器报告说,同时扩展或收缩所有 100 行平均只需要大约 0.3 秒。 Bottom line, I think you can achieve the optimizations you're looking for and not have to give up the conveniences of Vuetify.
最重要的是,我认为您可以实现您正在寻找的优化,而不必放弃 Vuetify 的便利。
v-data-table
inside a v-data-table
?v-data-table
内的v-data-table
吗?Here's what I did.这就是我所做的。 I created a simple Vue/Vuetify app with a
VDataTable
with 100 expandable rows.我创建了一个简单的 Vue/Vuetify 应用程序,其中包含一个具有 100 个可扩展行的
VDataTable
。 (The data was pulled from the random user API ). (数据来自随机用户 API )。 I used this method to count DOM nodes.
我使用这种方法来计算 DOM 节点。 Here are some of the parameters/info:
以下是一些参数/信息:
VSimpleTable
with the user's picture and addressVSimpleTable
vue create myapp
and vue add vuetify
vue create myapp
和vue add vuetify
的VDataTable
actually adds/removes the expansion rows from the DOM whenever the rows are expanded/contractedVDataTable
实际上会从 DOM 中添加/删除扩展行Here's some approximate stats on the result (these numbers fluctuated slightly in different conditions--YMMV):以下是结果的一些近似统计数据(这些数字在不同条件下略有波动——YMMV):
Here's code of the App.vue
page of my app.这是我的应用的
App.vue
页面的代码。 The v-data-table
almost the only component on the page (except the toggle button) and I didn't import any external components. 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>
You can see a working demo in this codeply .你可以在这个 codeply 中看到一个工作演示。 Hope this helps!
希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.