做者:Matthias Sommer翻譯:瘋狂的技術宅javascript
原文:https://dzone.com/articles/sp...html
未經容許嚴禁轉載前端
我有一個項目用了 Vue.js 來構建單頁應用程序。隨着上線日期的臨近,性能優化的工做變得愈來愈重要。在本文中,我收集了有關在加載時間和渲染性能方面提升 Vue.js 應用性能的全部知識。vue
使用 Vue.js,你能夠快速構建單頁應用。 Webpack 會爲你將全部內容捆綁到文件(HTML、JavaScript、CSS)中,最後能夠用 nginx 來提供。至少,這是咱們的設置。可是 Webpack 會警告你某些資源太大。java
須要注意的是,一旦用戶訪問 SPA,這三個文件將會被加載,而且只有在加載完畢以後纔會渲染頁面。可是最初加載的頁面通常不須要太多文件內容,而且不該拖慢用戶訪問咱們的網站的速度。webpack
如下介紹了有關如何緩解此類問題的幾種方法,以及在響應性和性能方面進一步改進 Vue.js 應用的其餘方法。ios
功能組件是不包含任何狀態和實例的組件。將無狀態 Vue 組件轉換爲功能組件能夠大大提升渲染性能。nginx
只需在頂層 template
標記中添加 functional
關鍵字便可:程序員
<template functional> <div>...</div> </template>
要像之前同樣訪問 prop 和數據,你必須進行一些小的調整。web
<template functional> <div>{{ props.someProp }}</div> </template> <script> export default { props: { someProp: String } } </script>
若是你使用 i18n 進行國際化,則必須在 parent 以前加上 $t
:
{{ parent.$t('app.not-found.message') }}
使用功能組件,咱們無權使用方法或計算的 prop。可是,咱們仍然可使用 $options
訪問方法。
<template functional> <div> {{ $options.username(props.user) }} </div> </template> <script> export default { props: { user: User, }, username(user: User): string { return user.name; } } </script>
延遲加載組件能夠節省大量的初始下載時間。調用 import()
函數時,將會下載全部延遲加載的資源。對於 Vue 組件,僅在請求渲染時才發生。對話框是註定會這樣的。一般僅在用戶交互後才顯示它們。
<template> <div> ... <app-modal-dialog v-if="showDialog" /> </div> </template> <script> export default { components: { ModalDialog: () => import('./ModalDialog.vue') } } </script>
Webpack 將爲 ModalDialog 組件建立一個單獨的塊,該塊不會在頁面加載時當即下載,而是僅在須要時才下載。
注意不要延遲加載應自動顯示的組件。例如如下內容(無提示)將沒法加載模式對話框。
mounted() { this.$bvModal.show('password-check'); },
緣由是已安裝的 hook 是在延遲加載模態組件以前進行評估的。
構建 SPA 時,JavaScript 捆綁包可能會變得很大,從而增長頁面加載時間。若是咱們能夠將每一個路由的組成部分拆分爲一個單獨的塊,而後僅在訪問路由時才加載它們,則效率會更高。
import ProjectList from '@/components/ProjectList.vue'; export const routes = [ { path: '/projects', name: 'projects', component: ProjectList, }, ]
定義一個異步組件很是容易,該組件將由 Webpack 自動進行代碼拆分。只需更改導入語句:
const ProjectList = () => import('@/components/ProjectList.vue');
除此以外,無需更改路由配置。經過如下方式在生產模式下構建你的應用:
"build": "vue-cli-service build --mode production"
並確認會生成不少塊
你還能夠經過在瀏覽器中打開開發者控制檯來驗證此功能是否正常。在 Network 標籤中,一旦你訪問新路由,就會異步加載多個 JavaScript 文件。在開發模式下,每一個塊都將被賦予一個自動遞增的數字。在生產模式下,將使用自動計算的哈希值代替。
Vue 有一個很酷的功能就是 Vue 自動添加 Webpack 的魔術註釋,以便進一步自動預取其餘塊(請參閱預取緩存一節) 。可是,預取僅在瀏覽器完成初始加載並變爲空閒以後纔開始。
一般,咱們將從後端獲取對象列表,例如用戶、項目、文章等。默認狀況下,Vue 使數組中每一個對象的每一個第一級屬性都具備響應性。對於大量對象而言,這代價可能會很大。有時咱們只想顯示對象時就不須要去修改它們。
因此在這種狀況下,若是咱們阻止 Vue 使列表具備響應性,那麼就能夠得到一些性能。咱們能夠經過使用列表中的 Object.freeze
來作到這一點,例如使其一直不變。
export async function get(url: string): Promise<User[]> { const response = await Object.freeze(axios.get<User[]>(url)); return response.data; }
咱們已經討論了許多改進 Vue SPA 的方法,可是不知道咱們實際得到了多少性能。能夠經過使用瀏覽器中開發者工具的 Performance 標籤來實現。
爲了得到準確的數據,咱們必須在 Vue 應用中激活性能模式。讓咱們在 main.ts 文件中用開發模式激活它
Vue.config.performance = process.env.NODE_ENV !== "production";
這將激活 Vue 內部使用的 User Timing API。
打開瀏覽器,而後按 F12 鍵打開開發者控制檯。切換到 Performance 選項卡,而後單擊 Start Profiling。在 Chrome 中,「 Timings」 行顯示重要標記,例如 「First Contentful Paint」 和 「First Meanfulful Paint」 時間。你應該嘗試減小它們,以便你的用戶能夠儘快使用該網站。
在本文中,咱們瞭解瞭如何對路由和組件使用延遲加載以將 SPA 分紅多個塊,功能組件如何提升性能以及如何衡量這些改進。