簡體   English   中英

VueJS,Vuetify,數據表 - 可擴展,性能問題

[英]VueJS, Vuetify, data-table - expandable, performance problem

我的 VueJS 和 Vuetify 項目有問題。 我想創建一個帶有可擴展行的表。 這將是一張訂單表,可以查看每個訂單的購買產品。 對於一頁,它應該顯示至少 100 行訂單。 為此,我使用了 Vuetify 框架<v-data-table>


問題是什么?

在准備好一切之后,我意識到它可以工作,但是對於每一行的擴展,我必須等待幾秒鍾(它太長了 - 它必須是一個快速的系統)。 並且為了擴展所有可見記錄,需要等待超過20 秒的整頁延遲。


我試過什么?

我從標准的 Vuetify <v-data-table>開始,帶有一個show-expand道具和一個 expand expanded-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更改為 none 應該比將整個對象添加/刪除到 DOM 問題更小。

這種方法比第一種方法快一點,但還是太慢了。

我找到了一個提示,為我的表中的每個v-btn設置:ripple="false"並且我做到了 - 有所幫助,但只有一點點。 一切都在 Chrome 和 Firefox、Windows 和 Linux Fedora 和兩部 ZC31B32364CE19CA8ZFCD1 智能手機的三台設備上進行了測試。


我還應該怎么做?

先感謝您!

這篇優秀的文章表明 DOM 節點的原始數量對性能的影響最大 也就是說,在我構建的示例應用程序中,我沒有遇到任何真正的性能瓶頸,以了解有關您的問題的更多信息。 包含表格的整個頁面在大約 1.25 秒內加載(來自本地主機),無論它是處於開發模式還是生產版本。 JavaScript控制台計時器報告說,同時擴展或收縮所有 100 行平均只需要大約 0.3 秒。 最重要的是,我認為您可以實現您正在尋找的優化,而不必放棄 Vuetify 的便利。

建議

  1. 考慮一次顯示更少的行(最大的預期影響)
  2. 簡化您的模板以使用盡可能少的元素,僅顯示用戶真正需要的數據。 您真的需要v-data-tablev-data-table嗎?
  3. 簡化您的數據 model 並僅檢索顯示表格所需的最少數據。 正如@Codeply-er 建議的那樣,數據的大小和復雜性可能會導致這種壓力

測試方法

這就是我所做的。 我創建了一個簡單的 Vue/Vuetify 應用程序,其中包含一個具有 100 個可擴展行的VDataTable (數據來自隨機用戶 API )。 我使用這種方法來計算 DOM 節點。 以下是一些參數/信息:

  • 行數:100
  • 列:5 + 擴展切換器
  • 擴展行內容:一個帶有用戶圖片和地址的VSimpleTable
  • 從 API 返回的單個 JSON 記錄的大小:~62 行(大約是上述示例 object 大小的一半)
  • Vue v2.6.11
  • Vuetify v2.3.0-beta.0
    (我意識到這剛剛出來,但我認為使用 v2.2.x 不會有不同的結果)
  • 應用程序是使用vue create myappvue add vuetify
  • 每當擴展/收縮行時, VDataTable實際上會從 DOM 中添加/刪除擴展行

以下是結果的一些近似統計數據(這些數字在不同條件下略有波動——YMMV):

  • 773 (~7/row): 100 行/5 列的 DOM 節點數,啟用擴展
  • 977(+2/行):啟用擴展節點數
  • 24:通過展開單行添加到表中的節點數
  • 3378(+26/行):擴展所有行的節點總數
  • 大約 1.25 秒在硬刷新時加載整個頁面
  • ~0.3s 同時擴展或收縮所有節點
  • 使用內置排序工具對列進行排序非常快速且非常有用

這是我的應用的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 中看到一個工作演示 希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM