Vue Lazy Loading
簡介
- 在 SPA 模式中,隨著專案規模變大,JS 檔案的加載時間也隨之變長
- 使用懶加載可以分割程式碼,需要時再載入,減少首次進入頁面加載時間
- 依靠於打包工具(Vite, Webpack) 代碼分割(Code Splitting)的功能
- 目的都是為了優化使用者體驗
路由懶加載
- 將每個路由頁面(Vue 檔案)分割成不同的塊(chunks),在訪問相應路由時才加載
不使用懶加載
- 所有頁面會在應用載入時一次性加載
import Home from './components/Home.vue'import About from './components/About.vue'import Contact from './components/Contact.vue'const routes = [ { path: '/', component: Home }, { path: '/about', component: About }, { path: '/contact', component: Contact }]
使用懶加載
- 當進入該路由時,再加載對應檔案
const Home = () => import('./components/Home.vue')const About = () => import('./components/About.vue')const Contact = () => import('./components/Contact.vue')const routes = [ { path: '/', component: Home }, { path: '/about', component: About }, { path: '/contact', component: Contact }]
元件懶加載
- 當有用到該元件的需求時,再進行載入,減少首次進入頁面加載時間
不使用懶加載
- 會在首次進入頁面時,一次性全部加載元件
創建MyComponent.vue
元件
// MyComponent.vue<template> <div> <!-- MyComponent的內容 --> </div></template><script>export default { // MyComponent的邏輯}</script>
在父元件中引入
// App.vue<template> <div> <MyComponent /> </div></template><script>import MyComponent from './components/MyComponent.vue'export default { components: { MyComponent }}</script>
使用懶加載
- 在父元件中,使用動態引入,在使用到該元件時才會被加載
<template> <div> <MyComponent v-if="isComponentVisible" /> </div></template><script>export default { data() { return { isComponentVisible: false } }, mounted() { // 假設某些條件或事件觸發顯示 setTimeout(() => { this.isComponentVisible = true }, 3000) }, components: { MyComponent: () => import('./components/MyComponent.vue') }}</script>
defineAsyncComponent
- 在 Vue3 當中新增的 API,用於更簡便處理異步元件的 Lazy Loading
- 創建異步元件
// AsyncComponent.vue<template> <div> <h2> {{ title }} </h2> </div></template><script setup>import { ref } from 'vue' // 異步元件的邏輯 const title = ref('大家好') ......</script>
- 在父元件中引入
// App.vue<template> <AsyncComponent v-if="show" /> <button @click="show = true">Show Component</button></template><script setup>import { ref } from 'vue'import { defineAsyncComponent } from 'vue'const show = ref(false)const AsyncComponent = defineAsyncComponent(() => import('./components/AsyncComponent.vue'))</script>
- 使用
defineAsyncComponent
時可以自定義一些設定
const AsyncComponent = defineAsyncComponent({ // the loader function loader: () => import('./components/AsyncComponent.vue'), // A component to use while the async component is loading loadingComponent: LoadingComponent, // Delay before showing the loading component. Default: 200ms. delay: 200, // A component to use if the load fails errorComponent: ErrorComponent, // The error component will be displayed if a timeout is // provided and exceeded. Default: Infinity. timeout: 3000})
- 可以和
Suspense
一起使用 - 加載過程中會顯示
#fallback
的 Loading...,優先於defineAsyncComponent
的設定
<template> <Suspense v-if="show"> <template #default> <AsyncComponent /> </template> <template #fallback> Loading... </template> </Suspense> <button @click="show = true">Show Component</button></template>
Webpack 的 Lazy Loading
- 允許開發者使用特定的語法(如 import())來標記代碼中的分割點
- 這些分割點告訴 Webpack 在這裡需要將代碼分割成不同的
chunks
- 這些
chunks
可以被單獨加載 - 在開發階段和生產階段都會進行完整的應用打包
例如:在 Vue Router 中新增一個路由
- 會將 Home.vue 及其依賴的代碼打包成一個獨立的
chunk
- 這個
chunk
在用戶訪問相應路由時才會被加載
const Home = () => import('./Home.vue')
參考資料
# Vue # LazyLoading