搜尋

首頁  >  問答  >  主體

Vue 3 提供/注入的效能如何?

<p>我從事的專案依賴應用程式層級 <code>provide</code> 進行全域狀態管理。起初,<code>provide</code>d 物件很小,但它隨著專案的發展而不斷成長。 </p> <p>在需要資料的地方注入該物件會對應用效能造成多大影響?如果沒有實作像 Pinia 這樣的全域狀態管理工具,是否值得將我們提供的大型物件分解為單獨的物件以在需要的地方提供資料「區塊」? </p>
P粉946336138P粉946336138455 天前547

全部回覆(1)我來回復

  • P粉854119263

    P粉8541192632023-08-27 00:50:55

    我已經做了一些基本的基準測試,想知道是否應該提供/注入經常使用的變量,或者是否應該從大量組件中的 Pinia 商店訪問它們。

    結果表明,沒有顯著的表現差異。

    我的第一個測試案例非常基本: 提供/注入單一 bool 與從元件中的 Pinia 儲存空間取得它並多次渲染元件不同。 50k 元件渲染花費的時間在 20-24 秒之間,使用提供/注入和使用 Pinia 時也是如此。沒有一致的差異可以說兩者中的任何一個更快/更慢。

    在第二個測試中,我使用了一個更大的對象,一個大約 1MiB 資料的陣列(以無空格 JSON 列印測量)。差異同樣不顯著。我已經渲染了 50k 元件,並且使用注入和儲存存取都花費了大約相同的時間,在 19-26 秒之間。

    每種情況下的元件都會渲染主題變數的布林值,因此它們的渲染時間不會因大數據與小布林值而增加。

    畢竟,我得出的結論是,provide/inject 與 Pinia 商店之間確實沒有任何有意義的區別。唯一明顯的差異是,當資料較大時,效能較不穩定,當資料較小時,效能更可預測。無論我對布林值重複測試多少次,時間總是在 20-24 秒之間,隨著資料的增加,我得到了一些異常值,例如 19 秒或 26 秒。再次沒有一致的情況,這可能只是我實際 CPU 使用率的波動,與 Provide/inject 與 Pinia store 的使用情況無關。

    我使用 vue@3.2.47 和 pinia@2.0.32 在 macOS 上的 Chrome v110 (x86_64) 上進行了測試。

    我使用的測試程式碼:

    <template>
      <div>Inject {{ number }}: {{ injected ? 'yes' : 'no' }}</div>
    </template>
    <script setup lang="ts">
      export interface Props {
        number?: number,
      }
      const props = withDefaults( defineProps<Props>(), {
        number: 0,
      })
      import { inject } from 'vue'
      const injected = inject('inject-test')
    </script>
    
    <template>
      <div>Store get {{ number }}: {{ testStore.test ? 'yes' : 'no' }}</div>
    </template>
    <script setup lang="ts">
      export interface Props {
        number?: number,
      }
      const props = withDefaults( defineProps<Props>(), {
        number: 0,
      })
      import { useTestStore } from 'stores/test'
      const testStore = useTestStore()
    </script>
    
    <template>
      <div v-if="testStore">
        <h1>Store get</h1>
        <pre>Start: {{ start() }}</pre>
        <div class="test">
          <StoreGet v-for="n in 50000"
                    :key="n"
                    :number="n"
          />
        </div>
        <pre>End: {{ end() }}</pre>
        <pre>Duration: {{ endTime - startTime }} seconds</pre>
      </div>
      <div v-else>
        <h1>Inject</h1>
        <pre>Start: {{ start() }}</pre>
        <div class="test">
          <Inject v-for="n in 50000"
                  :key="n"
                  :number="n"
          />
        </div>
        <pre>End: {{ end() }}</pre>
        <pre>Duration: {{ endTime - startTime }} seconds</pre>
      </div>
    </template>
    
    <script setup lang="ts">
      import { provide } from 'vue'
      import Inject from './test/Inject.vue'
      import StoreGet from './test/StoreGet.vue'
    
      // Roughly 1M of json data
      import { large } from '@sbnc/datasets/largeTest'
    
      // Comment one or the other:
      const testData = true
      //const testData = large
    
      // Choose which one to test:
      const testStore = true // set false to test inject
    
      provide( 'inject-test', testData)
    
      import { useTestStore } from 'stores/test'
      const testStore = useTestStore()
      testStore.test = testData
    
      let startTime
      let endTime
    
      function start() {
        startTime = performance.now()
        return startTime
      }
      function end() {
        endTime = performance.now()
        return endTime
      }
    </script>
    

    回覆
    0
  • 取消回覆