現在,webpack
毫無疑問是前端構建領域裏最耀眼的一顆星,不管你前端走哪條路線,都須要有很強的webpack
知識。webpack
的基本用法這裏就不展開講了。主要探討一下如何提升 webpack
的打包速度。css
這篇文章以
vue cli3.0+
,webpack4.0+
,nodejs10.0+
這幾個版本爲例。html
咱們的目的是優化打包速度,那確定須要一個速度分析插件,此時 speed-measure-webpack-plugin
就派上用場了。它的做用以下:前端
plugin
和 loader
的耗時狀況首先,安裝插件vue
npm i -D speed-measure-webpack-plugin
而後修改 vue.config.js
配置文件 (vuecli3+
版本的配置文件統一在這個文件裏修改,若是沒有該文件,在根目錄新建一個)node
// 導入速度分析插件 const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); // 實例化插件 const smp = new SpeedMeasurePlugin(); module.exports = { configureWebpack: smp.wrap({ plugins: [ // 這裏是本身項目裏須要使用到的其餘插件 new yourOtherPlugin() ] }) }
運行打包命令以後,能夠看到,打包總耗時爲 2min,51.99s
webpack
分析完打包速度以後,接着咱們來分析打包以後每一個文件以及每一個模塊對應的體積大小。使用到的插件爲 webpack-bundle-analyzer
,構建完成後會在 8888
端口展現大小。ios
首先,安裝插件web
npm i -D webpack-bundle-analyzer
修改 vue.config.js
配置文件vue-router
// 導入速度分析插件 const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); // 導入體積分析插件 const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; // 實例化速度分析插件 const smp = new SpeedMeasurePlugin(); module.exports = { configureWebpack: smp.wrap({ plugins: [ // 實例化體積分析插件 new BundleAnalyzerPlugin() ] }) }
構建以後能夠看到,其中黃色塊 chunk-vendors
文件佔比最大,爲 1.34MB
vuex
多進程構建的方案比較知名的有如下三個:
這裏以 thread-loader
爲例配置多進程多實例構建
安裝 loader
npm i -D thread-loader
接下來在 vue.config.js
配置文件中使用該 loader
// 導入速度分析插件 const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); // 實例化插件 const smp = new SpeedMeasurePlugin(); module.exports = { configureWebpack: smp.wrap({ module: { rules: [ { test: /\.js$/, use: ['thread-loader'] } ] } }) }
而後看下構建花費的時間, 2min,49.21s
,相較於以前提高了 5s
對於vue,vuex,vue-router,axios,echarts,swiper等咱們能夠利用webpack的externals參數來配置,這裏咱們設定只須要在生產環境中才須要使用。
下面配置 vue.config.js
// 導入速度分析插件 const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); // 導入體積分析插件 const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; //判斷是否爲生產環境 const isProduction = process.env.NODE_ENV === 'production'; //定義 CDN 路徑,這裏採用 bootstrap 的 cdn const cdn = { css: [ 'https://cdn.bootcss.com/Swiper/4.5.1/css/swiper.min.css' ], js: [ 'https://cdn.bootcss.com/vue/2.6.10/vue.min.js', 'https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js', 'https://cdn.bootcss.com/vuex/3.1.1/vuex.min.js', 'https://cdn.bootcss.com/axios/0.19.0/axios.min.js', 'https://cdn.bootcss.com/echarts/4.3.0/echarts.min.js', 'https://cdn.bootcss.com/Swiper/4.5.1/js/swiper.min.js', ] } // 實例化插件 const smp = new SpeedMeasurePlugin(); module.exports = { chainWebpack: config => { // 生產環境配置 if (isProduction) { // 生產環境注入 cdn config.plugin('html') .tap(args => { args[0].cdn = cdn; return args; }); } }, configureWebpack: smp.wrap({ module: { rules: [ { test: /\.js$/, use: ['thread-loader'] } ] }, plugins: [ new BundleAnalyzerPlugin() ], //生產環境注入 cdn externals: isProduction && { 'vue': 'Vue', 'vuex': 'Vuex', 'vue-router': 'VueRouter', 'axios': 'axios', 'echarts': 'echarts', 'swiper': 'Swiper' } || {} }) }
緊接着,改造 html
頁面。用於讓咱們配置的 cdn
路徑注入到 html
頁面
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <!-- 使用 CDN 的 CSS 文件 --> <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %> <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet"> <% } %> </head> <body> <noscript> <strong>We're sorry but eye-admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> <!-- 使用 CDN 的 JS 文件 --> <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %> <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script> <% } %> </body> </html>
最重要的一步,看下效果,能夠看到如今耗時 1min,39.19s
,整整提高了 1 分多鐘!
並行壓縮主流有如下三種方案
安裝插件依賴
npm i -D terser-webpack-plugin
接下來在 vue.config.js
配置文件中使用插件,最終的配置文件以下
// 導入速度分析插件 const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); // 導入代碼壓縮插件 const TerserPlugin = require("terser-webpack-plugin"); // 導入體積分析插件 const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; //判斷是否爲生產環境 const isProduction = process.env.NODE_ENV === 'production'; //定義 CDN 路徑,這裏採用 bootstrap 的 cdn const cdn = { css: [ 'https://cdn.bootcss.com/Swiper/4.5.1/css/swiper.min.css' ], js: [ 'https://cdn.bootcss.com/vue/2.6.10/vue.min.js', 'https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js', 'https://cdn.bootcss.com/vuex/3.1.1/vuex.min.js', 'https://cdn.bootcss.com/axios/0.19.0/axios.min.js', 'https://cdn.bootcss.com/echarts/4.3.0/echarts.min.js', 'https://cdn.bootcss.com/Swiper/4.5.1/js/swiper.min.js', ] } // 實例化插件 const smp = new SpeedMeasurePlugin(); module.exports = { chainWebpack: config => { // 生產環境配置 if (isProduction) { // 生產環境注入 cdn config.plugin('html') .tap(args => { args[0].cdn = cdn; return args; }); } }, configureWebpack: smp.wrap({ module: { rules: [ { test: /\.js$/, use: ['thread-loader'] } ] }, plugins: [ new BundleAnalyzerPlugin() ], //生產環境注入 cdn externals: isProduction && { 'vue': 'Vue', 'vuex': 'Vuex', 'vue-router': 'VueRouter', 'axios': 'axios', 'echarts': 'echarts', 'swiper': 'Swiper' } || {}, optimization: { minimizer: [ new TerserPlugin({ parallel: 4 }) ] } }) }
動態 polyfill
指的是根據不一樣的瀏覽器,動態載入須要的 polyfill
。 Polyfill.io
經過嘗試使用 polyfill
從新建立缺乏的功能,能夠更輕鬆地支持不一樣的瀏覽器,而且能夠大幅度的減小構建體積。
識別 User Agent,下發不一樣的 Polyfill
使用方法:在 index.html
中引入以下 script
標籤
<script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js"></script>
轉載請註明出處:https://www.jianshu.com/p/481e7214a134
做者:TSY
我的空間:https://hxkj.vip