В этой превосходной статье предполагается, что необработанное количество узлов DOM оказывает наибольшее влияние на производительность . Тем не менее, я не испытывал каких-либо реальных узких мест в производительности в образце приложения, которое я создал, чтобы узнать больше о вашей проблеме. Вся страница с таблицей загружается примерно за 1,25 с (из localhost), независимо от того, была ли она в режиме разработки или это была производственная сборка. Консольный таймер JavaScript сообщил, что расширение или сжатие ВСЕХ 100 строк одновременно заняло в среднем около 0,3 с. В итоге, я думаю, что вы можете достичь оптимизации, которую вы ищете, и не должны отказываться от удобства Vuetify.
Рекомендации
- Рассмотрите возможность отображения меньшего количества строк одновременно ( наибольшее ожидаемое влияние)
- Оптимизируйте свой шаблон, чтобы использовать как можно меньше элементов, отображать только те данные, которые действительно необходимы пользователям. Вы действительно нуждаетесь в
v-data-table
внутри a v-data-table
? - Оптимизируйте свою модель данных и извлекайте только те минимальные данные, которые необходимы для отображения таблицы. Как предположил @ Codeply-er, размер и сложность ваших данных могут быть причиной такого напряжения
Метод тестирования
Вот что я сделал. Я создал простое приложение Vue / Vuetify с VDataTable
с 100 расширяемыми строками. (Данные были получены из API случайного пользователя ). Я использовал этот метод для подсчета узлов DOM. Вот некоторые параметры / информация:
- Строки: 100
- Столбцы: 5 + переключатель расширения
- Содержимое строки расширения: a
VSimpleTable
с изображение и адрес пользователя - Размер одной JSON записи, возвращаемой из API: ~ 62 строки (примерно вдвое меньше размера вашего образца объекта выше)
- Vue v2.6.11
- Vuetify v2.3.0-beta.0
(я понимаю, что это только что вышло, но я не думаю, что вы получите другие результаты, используя v2.2.x) - Приложение было создано с
vue create myapp
и vue add vuetify
VDataTable
фактически добавляет / удаляет строки расширения из DOM всякий раз, когда строки расширяются / сжимаются
Вот приблизительная статистика результата (эти числа слегка колебались в разных условиях - YMMV):
- 773 (~ 7 / строка): количество узлов DOM в 100 строках / 5 столбцов без расширение включено
- 977 (+ 2 / строка): количество узлов с расширение включено
- 24: количество узлы, добавленные в таблицу путем расширения одной строки
- 3378 (+ 26 / строки): общее количество узлов со ВСЕМИ развернутыми строками
- ~ 1,25 с для загрузки всей страницы на жестком обновлении sh
- ~ 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>
Вы можете увидеть рабочую демонстрацию в этом codeply . Надеюсь, это поможет!