本文中全部的測試都基於 2017款15寸MacBook Pro低配版本html
關於dll的介紹已經有不少文章了,webpack性能優化都無可避免的會提到dll。在webpack 4已經進入生涯晚期,webpack 5已經發了幾十個alpha版本的時間節點,咱們是否還須要dll這個優化手段。vue
dll的做用是將項目中一些不常改變的依賴單獨打包,webpack經過生成的manifest文件去引用對應的依賴。node
webpack 4相比於3增長了不少新的特性,而且根據mode增長了不少的默認配置。react
其中和dll關係比較大的改變是在webpack 4中用terser來對文件進行壓縮混淆,替換了原來的uglifyjs,而且默認開啓了多進程和緩存。webpack
@vue/cli在3.0的版本中再也不支持dll,可能也和webpack 4在打包的時候默認開啓緩存有關,由於dll說到底其實也是一種文件的緩存機制。web
那咱們是否再也不須要dll呢?json
通常的項目開發過程當中,都避不開兩個場景。一個是本地開發,須要運行webpack-dev-server啓動一個本地服務;一個是線上發佈,須要運行build命令,對項目進行打包而後進行代碼發佈。緩存
對於項目打包,特別是升級到webpack 4之後,dll就顯得有點不合時宜。一方面是由於terser的緩存機制已經很優秀了,另外一方面是由於webpack 4中的sideEffects機制。性能優化
在webpack 4 中增長了sideEffects機制,一個包若是在package.json中聲明瞭sideEffects爲false,那麼webpack會認爲這個包中的各個模塊是無反作用的,對於沒有用到的模塊就不會去加載,作到了文件級別的按需加載。對於那些已經使用了sideEffects來實現按需加載的包,咱們在最終項目打包的時候能夠作到按需打包,不會對這個包作全量引入。相似的還有lodash和antd這些經過babel插件來實現按需引入的包,最終打包的時候也不會全量引入整個包。babel
可是若是使用dll來處理這些第三方依賴的包,就會把這個包全量引入進來,最終的代碼裏會有不少多餘的代碼,最終代碼的大小也會增長不少。
webpack對於依賴的收集,會從配置的入口文件開始,去作遞歸的解析,最後生成一個依賴圖。
在每次運行dev-server的時候,webpack都會從新去收集全部的依賴。terser只會在打包壓縮的時候纔會運行,因此在dev的時候是沒有辦法進行緩存的。babel-loader也能夠進行緩存設置,可是通常的項目爲了加快構建速度,都會默認不去處理node_modules裏面的依賴,因此第三方的依賴包沒法被編譯緩存。
在這種狀況下,dll的引入就會帶來巨大的性能提高。使用dll對第三方依賴進行緩存,只要依賴版本不變動,那麼webpac依賴解析就能夠跳過全部node_modules裏面的依賴文件,大大減小dev-server的啓動時間。
對於時間的測試,若是隻是使用腳手架create一個沒有什麼依賴的空項目,那不會有任何意義。
爲了還原真實場景的數據,這裏將用一個PC的項目進行測試。主要的依賴有react全家桶、@babel/polyfill、antd和loadsh。可是項目的業務代碼並非不少,因此在某些時間上面可能會有必定的誤差。
絕大多數使用了緩存進行優化的項目,在項目第一次運行的時候都不會有效果,由於這時候的緩存文件尚未生成。
在僅使用babel-loader緩存的狀況下,dev-server的啓動時間以下
類型 | 啓動時間 |
---|---|
首次啓動 | 22s |
第二次 | 17.7s |
第三次 | 18.1s |
第四次 | 17.8s |
能夠看出在首次啓動的時候,由於babel-loader尚未緩存,因此這時候啓動時間最長。當緩存生成之後,啓動時間就會有一個減小。
當啓用dll之後,啓動時間以下
類型 | 啓動時間 |
---|---|
首次啓動 | 27.6s |
第二次 | 5.1s |
第三次 | 4.8s |
第四次 | 4.9s |
在首次啓動的時候,花費的時間比沒有dll的要多一些,其中生成dll文件的時間爲19s。可是當dll文件生成之後,再次啓動的時間會有巨大幅度的減小,由於webpack對於dll中的依賴不用再作任何的解析和處理。
hard-source-webpack-plugin也提供了緩存系統,能夠做爲dll的代替方案。
相比於dll,它配置更簡單,只須要增長一個plugin配置便可。可是在項目啓動時間上,要比dll的方案慢一秒左右。
類型 | 啓動時間 |
---|---|
首次啓動 | 21.8s |
第二次 | 6.1s |
第三次 | 6.3s |
第四次 | 6.0s |
可是在項目打包的時候,hard-source-webpack-plugin帶來的提高是巨大的。緩存生成之後,build的時間從15s減小到5s。
不過hard-source-webpack-plugin中止維護快一年的時間了,這可能也是一個須要考慮的問題;另外一個須要考慮的問題是它的緩存文件很是大,會佔用很是多的硬盤空間。
在同時開啓dll和hard-source-webpack-plugin的時候,當緩存同時生效的狀況下,項目啓動只須要兩秒左右的時間,相比於開啓單個功能,時間分別減小了一半和三分之二。
類型 | 啓動時間 |
---|---|
首次啓動 | 27.3s |
第二次 | 2.1s |
第三次 | 2.1s |
第四次 | 2.2s |
webpack 5的alpha版本最近增長的很快,做者已經加快了開發速度。webpack 5中實驗性的內置了一個文件緩存系統,能夠徹底替代hard-source-webpack-plugin、babel-loader以及一系列的緩存方案。
可是如今還有不少webpack的第三方插件沒有對webpack 5作兼容,好比html-webpack-plugin。但願webpack 5正式發佈的時候可以獲得解決。
在webpack 5到來以前,使用hard-source-webpack-plugin,配合babel-loader,能得到至關可觀的緩存優化。
本地開發階段若是加入dll,可使得項目啓動時間進一步減小,縮短等待項目啓動的發呆時間。