在版本更新迭代、新代碼上線後,若是用戶須要從新從服務器加載所有資源(js、css),確定會讓頁面打開變慢,這實際上是沒有必要的。css
爲了優化用戶體驗,提升頁面打開速度,能夠將js拆分紅多個模塊,每次有更新,用戶只須要加載更新了的業務代碼便可,這就是分包。html
通常來講,前端項目無論框架是什麼,大可能是基於webpack打包的,好比umi、next、nuxt、vue-cli,因此本文只基於webpack打包工具給出方案。前端
webpack4提供了 splitChunks 插件,就是用來作代碼分割的,具體使用方法能夠查看官方文檔。vue
比較廣泛的分包策略是按照體積大小、共用率、更新頻率從新劃分咱們的包,使其儘量的利用瀏覽器緩存。node
根據這一策略給出通用的分包方案,將js拆分紅如下三個模塊:webpack
所以,每次發佈代碼以後一般須要更新的只有三、而1和2直接從瀏覽器緩存中讀取便可。git
以phoenix項目爲例,目前的線上頁面打包後的狀況以下圖:
經過分析工具看看各個模塊是什麼:
github
在什麼都不作的狀況下umi其實已經默認分包了,這是由於其內置的webpack提供了默認分包策略:web
使用上述方案對默認分包策略進行優化,將UI庫提取出來,在配置文件(umirc.ts)中加入自定義分包代碼:vue-cli
config.optimization.splitChunks({ chunks: 'async', minSize: 30000, maxSize: 0, minChunks: 1, maxAsyncRequests: 5, maxInitialRequests: 3, automaticNameDelimiter: '~', name: true, cacheGroups: { vendors: { name: 'vendors', test: /[\\/]node_modules[\\/]/, priority: -10, }, antdesigns: { name: 'antdesigns', test: /[\\/]node_modules[\\/]antd-mobile[\\/]/, priority: -9, } } })
各個字段的表示的含義再也不此贅述,可查看官方文檔。主要看cacheGroups,把antd提取了出來。
再來看下打包以後的效果:
多了一個antdesigns.js,成功將antd提取出來。
Q:其實這裏能夠思考一下,將antd提取到底合不合適?
A:phoenix項目是個多頁面應用,目前頁面數量很少,而antd也支持按需引入,將antd代碼打包進各個頁面的業務代碼或者node_modules中也不會增長多少體積,而antd代碼體積並不大,單獨提取出來後須要多一次http連接,感受沒有必要。不過隨着之後項目體積變大,也就不必定了。因此各個項目仍是要根據自身狀況進行分包。
分包是一個博弈的過程,是讓 a bundle 大一點仍是 b?
是讓首次加載快一點仍是讓 cache 的利用率高一點?
但有一點要切記,拆包的時候不要過度的追求顆粒化,什麼都單獨的打成一個 bundle,否則你一個頁面可能須要加載十幾個js文件,若是你還不是HTTP/2的狀況下,請求的阻塞仍是很明顯的(受限於瀏覽器併發請求數)。
因此仍是那句話資源的加載策略並沒什麼徹底的方案,都須要根據項目自身狀況進行分包。
分包以後的下一步就是充分使用瀏覽器緩存,首先須要把靜態資源放到cdn上,再設置合理的緩存策略,只要chunk的hash沒有改變,都從瀏覽器緩存讀取。
參考資料:https://panjiachen.github.io/...
文/小辰
關注得物技術,攜手走向技術的雲端