翻譯:瘋狂的技術宅
我有一個專案用了 Vue.js 來構建單頁應用程式。隨著上線日期的臨近,效能優化的工作變得越來越重要。在本文中,我收集了有關在載入時間和渲染效能方面提高 Vue.js 應用效能的所有知識。
使用 Vue.js,你可以快速構建單頁應用。Webpack 會為你將所有內容捆綁到檔案(HTML、JavaScript、CSS)中,最後可以用 nginx 來提供。至少,這是我們的設定。但是 Webpack 會警告你某些資源太大。
需要注意的是,一旦使用者訪問 SPA,這三個檔案將會被載入,並且只有在載入完畢之後才會渲染頁面。但是最初載入的頁面一般不需要太多檔案內容,並且不應拖慢使用者訪問我們的網站的速度。
前面小編也整理過關於Vue和Reate 相關的效能優化相關文章,具體學習文章請見本篇文章底部
以下介紹了有關如何緩解此類問題的幾種方法,以及在響應性和效能方面進一步改進 Vue.js 應用的其他方法。
功能元件功能元件是不包含任何狀態和例項的元件。將無狀態 Vue 元件轉換為功能元件可以大大提高渲染效能。
只需在頂層 template 標記中新增 functional 關鍵字即可:
1<template functional> <div>...</div> </template>
要像以前一樣訪問 prop 和資料,你必須進行一些小的調整。
1<template functional> 2 <div>{{ props.someProp }}</div> 3</template> 4<script> 5 export default { 6 props: { 7 someProp: String 8 } 9 }10</script>
如果你使用 i18n 進行國際化,則必須在 parent 之前加上 $t:
1{{ parent.$t('app.not-found.message') }}
使用功能元件,我們無權使用方法或計算的 prop。但是,我們仍然可以使用 $options 訪問方法。
1<template functional> 2 <div> 3 {{ $options.username(props.user) }} 4 </div> 5</template> 6<script> 7 export default { 8 props: { 9 user: User, 10 }, 11 username(user: User): string { 12 return user.name; 13 } 14 }15</script>
延遲載入元件延遲載入元件可以節省大量的初始下載時間。呼叫 import() 函式時,將會下載所有延遲載入的資源。對於 Vue 元件,僅在請求渲染時才發生。對話方塊是註定會這樣的。通常僅在使用者互動後才顯示它們。
1<template> 2 <div> 3 ... 4 <app-modal-dialog v-if="showDialog" /> 5 </div> 6</template> 7<script> 8 export default { 9 components: { 10 ModalDialog: () => import('./ModalDialog.vue') 11 } 12 }13</script>
Webpack 將為 ModalDialog 元件建立一個單獨的塊,該塊不會在頁面載入時立即下載,而是僅在需要時才下載。
注意不要延遲載入應自動顯示的元件。例如以下內容(無提示)將無法載入模式對話方塊。
1mounted() {2 this.$bvModal.show('password-check'); 3},
原因是已安裝的 hook 是在延遲載入模態元件之前進行評估的。
延遲載入路由構建 SPA 時,JavaScript 捆綁包可能會變得很大,從而增加頁面載入時間。如果我們可以將每個路由的組成部分拆分為一個單獨的塊,然後僅在訪問路由時才載入它們,則效率會更高。
1import ProjectList from '@/components/ProjectList.vue'; 2export const routes = [ 3 { 4 path: '/projects', 5 name: 'projects', 6 component: ProjectList, 7 }, 8]
定義一個非同步元件非常容易,該元件將由 Webpack 自動進行程式碼拆分。只需更改匯入語句:
1const ProjectList = () => import('@/components/ProjectList.vue');
除此之外,無需更改路由配置。通過以下方式在生產模式下構建你的應用:
1"build": "vue-cli-service build --mode production"
並確認會生成很多塊
Vue 和 Webpack 中的程式碼拆分你還可以通過在瀏覽器中開啟開發者控制檯來驗證此功能是否正常。在 Network 標籤中,一旦你訪問新路由,就會非同步載入多個 JavaScript 檔案。在開發模式下,每個塊都將被賦予一個自動遞增的數字。在生產模式下,將使用自動計算的雜湊值代替。
延遲載入的塊和預取快取Vue 有一個很酷的功能就是 Vue 自動新增 Webpack 的魔術註釋 (/file/2020/04/29/20200429042447_201074.jpg 。但是,預取僅在瀏覽器完成初始載入並變為空閒之後才開始。
使物件列表不可變通常,我們將從後端獲取物件列表,例如使用者、專案、文章等。預設情況下,Vue 使陣列中每個物件的每個第一級屬性都具有響應性。對於大量物件而言,這代價可能會很大。有時我們只想顯示物件時就不需要去修改它們。
所以在這種情況下,如果我們阻止 Vue 使列表具有響應性,那麼就可以獲得一些效能。我們可以通過使用列表中的 Object.freeze 來做到這一點,例如使其一直不變。
1export async function get(url: string): Promise<User[]> { 2 const response = await Object.freeze(axios.get<User[]>(url)); 3 return response.data; 4}
評估執行時效能
我們已經討論了許多改進 Vue SPA 的方法,但是不知道我們實際獲得了多少效能。可以通過使用瀏覽器中開發者工具的 Performance 標籤來實現。
為了獲得準確的資料,我們必須在 Vue 應用中啟用效能模式。讓我們在 main.ts 檔案中用開發模式啟用它
1Vue.config.performance = process.env.NODE_ENV !== "production";
這將啟用 Vue 內部使用的 User Timing API (https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API。
開啟瀏覽器,然後按 F12 鍵開啟開發者控制檯。切換到 Performance 選項卡,然後單擊 Start Profiling。在 Chrome 中,“ Timings” 行顯示重要標記,例如 “First Contentful Paint” 和 “First Meanfulful Paint” 時間。你應該嘗試減少它們,以便你的使用者可以儘快使用該網站。
總結在本文中,我們了解了如何對路由和元件使用延遲載入以將 SPA 分成多個塊,功能元件如何提高效能以及如何衡量這些改進。
翻譯:瘋狂的技術宅