Vue 元件太肥,切換頁面卡卡怎麼辦?讓 Suspense 登場吧!

use-suspense-to-load-components-asynchronously

醜話說在前頭,切換頁面卡卡有很多種原因,這裡舉的例子只針對元件太大的情境喔。( •̀ ω •́ )✧

甚麼樣的情況會讓元件太大呢?有可能是 HTML、CSS 太多,但最常見的情況就是包了太多 JS 在一起了。╮(╯▽╰)╭(import 一大堆套件等等)

除了想辦法拆分外,還有一個方法就是利用 Vue 的 Async Component。

Async Component 是什麼?

甚麼是 Async Component?簡單來說就是在真的要用的時候才從 server 下載元件,如果熟悉 Vue Router 的朋友們對以下寫法一定不陌生:

const router = createRouter({
  // ...
  routes: [
    { 
      path: '/users/:id', 
      component: () => import('./views/UserDetails.vue') 
    },
  ],
})

這個在 Vue Router 中被稱為 Lazy Loading Routes

此概念與 Async Component 概念相同,編譯、打包時會將每個頁面拆分,只有在真的需要某頁面元件時,才從 server 下載,才不會讓進入網頁的使用者等待下載一堆還不會用到的頁面。

讓我們來一個簡單的範例:

App.vue

<script setup>
import { defineAsyncComponent } from 'vue';
import FatComp from './components/FatComp.vue';

</script>

<template>
  Vue Suspense

  <hr />

  <FatComp />
</template>

其中 FatComp 是一個和鱈魚一樣超肥的元件,會顯示「很大很大的元件」。

鱈魚:「說好的尊重呢?(゚Д゚*)ノ」

如果我們直接 import 元件,就必須等待元件下載完成,App.vue 的畫面才會出現。

同步載入

可以注意到 Vue Suspense 的文字會等到 FatComp 載入完成後才會顯示。

如果我們使用 Suspense 改寫:

<script setup>
import { defineAsyncComponent } from 'vue';

const AsyncFatComp = defineAsyncComponent(() =>
  import('./components/FatComp.vue')
);
</script>

<template>
  Vue Suspense

  <hr />

  <Suspense>
    <AsyncFatComp />

    <template #fallback> Loading... </template>
  </Suspense>
</template>

非同步載入

可以看到 Vue Suspense 字樣先出現,肥肥的元件則會等到下載完成才出現。

恭喜頁面不卡了!✧⁑。٩(ˊᗜˋ*)و✧⁕。

Suspense 元件詳細說明可以來官方文件看看。

以上範例程式在此,我們下次再見囉!(´▽`ʃ♡ƪ)

總結 🐟

  • 肥大元件請用 Async Component
  • 配合 Suspense 可以讓頁面有更好的使用者體驗