爲你的 Vue.js 單頁應用提速

做者: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"

並確認會生成不少塊

Vue 和 Webpack 中的代碼拆分

你還能夠經過在瀏覽器中打開開發者控制檯來驗證此功能是否正常。在 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 分紅多個塊,功能組件如何提升性能以及如何衡量這些改進。


本文首發微信公衆號:前端先鋒

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎繼續閱讀本專欄其它高贊文章:


相關文章
相關標籤/搜索