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