Vue.js應用性能優化二

Vue.js應用性能優化二

在 文章中,我們瞭解了代碼拆分是什麼,它如何與Webpack一起工作以及如何在Vue應用程序中使用延遲加載來使用它。現在我們將深入研究代碼,並學習最有用的Vue.js應用程序代碼分割模式。


系列文章:


通過使用以下技術,我們能夠將初始bundle的大小減少70%並使其在眨眼間加載。

應用規模增長帶來的問題

Vue-router是一個庫,允許自然地將我們的Web應用程序拆分為單獨的頁面。每個頁面都是與某個特定URL路徑關聯的路由。

知道這一點,我們有一個簡單的應用程序,具有以下結構:

Vue.js應用性能優化二

Vue.js應用性能優化二

所有js代碼都被打包到一個文件 — app.js

您可能已經注意到,根據我們訪問的路由,我們可能不需要Home.vue或About.vue(依賴lodash)但它們都在相同的app.js包中,無論路由用戶是什麼,都會被下載訪問。浪費下載和解析時間!

如果我們只是多下載了一個路由,那這並不是什麼大問題。但你可以想象,隨著這個應用程序越來越大,任何新的添加都意味著在首次訪問時下載更大的bundle。

當1秒的時間足以讓用戶心裡犯嘀咕,並且(可能)離開我們的網站時,這是不可接受的!

不同延遲,用戶的心理反應:

  • 0 - 100ms,感覺很快
  • 100 - 300ms 可以接受的延遲等待
  • 300 - 1000ms 盯著網頁,明顯感覺到延遲
  • 1000+ms 心裡開始嘀咕,要不要離開
  • 10,000+ms 先去別的地方逛逛吧,稍後見

使用vue-router進行基於路由的代碼分割

為了避免弄巧成拙,我們只需要使用我們在前一篇文章中學習的動態導入語法,為每個路由創建單獨的bundle。

像Vue.js中的其他所有東西一樣 - 它非常簡單。我們只需要在那裡動態導入組件,而不是將組件直接導入到路徑對象中。僅當解析給定路線時才會下載路線組件。

所以不要像這樣靜態導入路徑組件:

Vue.js應用性能優化二

我們需要動態導入它,這將創建一個包含此路由的新bundle作為入口點:

Vue.js應用性能優化二

知道了這一點,讓我們看看我們的捆綁和路由如何與動態導入一樣:

Vue.js應用性能優化二

home.js,about.js 都被拆分成單獨的bundle

Vue.js應用性能優化二

通過此設置,webpack將創建三個包:

  • app.js - 我們的主要包含應用程序入口點(main.js)和每個路由所需的庫/組件
  • home.js - home頁面bundle,只有在輸入/路徑時才會下載
  • about.js - about頁面bundle(依賴 lodash),只有在輸入路徑為/about時才會下載

bundle名稱不是webpack生成的真實名稱,以便於理解。 Webapck實際上正在生成類似0.js 1.js等,具體取決於您的webpack配置。

這種技術幾乎適用於所有應用,並且可以提供非常好的效果。

在許多情況下,基於路由的代碼拆分將解決您的所有性能問題,並且可以在幾分鐘內應用於幾乎任何應用程序!

Vue生態系統中的代碼拆分

您可能正在使用Nuxt或vue-cli來創建您的應用程序。如果是這樣,重要的是要知道它們都有關於代碼拆分的一些自定義行為:

  • 在vue-cli 3中,默認情況下將預取所有延遲加載的塊。我們將在稍後學習如何使用預取(prefetching)。
  • 在Nuxt中,如果我們使用Nuxt路由系統,所有頁面路由都是開箱即用的

現在讓我們來看看非常流行且常用的反模式,它會減弱基於路由的代碼拆分效果。

Vendor bundle 反模式

vendor包(第三方類庫)通常用於包含node_modules中所有模塊的單獨js文件的上下文中。

雖然可以將所有內容放在這裡,將所有依賴項保存在一個地方並緩存它們,感覺上可能很好,但這種方法帶來了將所有路由打包在一起時遇到的相同問題:

Vue.js應用性能優化二

黃色模塊,都是vendor

你看到了問題嗎?即使我們只需要在一個路由中使用lodash(它是其中一個依賴項),但是現在它被捆綁在vendor.js中以及所有其他依賴項中,因此它將始終下載。

將所有依賴項打包在一個文件中聽起來很好,但會使您的應用加載時間更長。我們可以做得更好!

如果按照基於路由的代碼分割方式,會確保所有依賴的代碼被下載。但同時也會重複下載一些相同的依賴。比如兩個路由頁面中都依賴lodash的情況。

讓我們假設Home.vue也需要lodash。

Vue.js應用性能優化二

在這種情況下,從/about(About.vue)導航到/(Home.vue)將最終導致兩次下載lodash。

它仍然比下載大量的冗餘代碼更好,但是如果我們已經有了這種依賴,那麼重用它就沒有意義了,對吧?

這是webpack splitChunksPlugin可以幫助我們的地方。只需將這幾行添加到webpack配置中,我們就會將公共依賴項分組到一個單獨的包中,以便共享它們。再說的清楚一些,幾個路由頁面共享的依賴,會單獨抽取出來打包,而其他頁面不會下載這個共享包。整個應用有一個全局共享的vendor bundle。

Vue.js應用性能優化二

chunks屬性中,我們只是告訴webpack應該優化哪些代碼塊。您可能已經猜到了,將此屬性設置為all,這意味著它應該優化所有代碼塊。

您可以在webpack文檔中閱讀有關此過程的更多信息

總結

按路由拆分代碼是降低初始bundle大小的最佳(也是最簡單)方法之一。在下一部分中,我們將瞭解所有其他小部件(Vuex存儲和單個組件),這些部件也可以從主bundle中減掉並且懶加載。


分享到:


相關文章: