1. 程式人生 > 其它 >vue webpack壓縮程式碼_【原創】webpack如何優化vue專案

vue webpack壓縮程式碼_【原創】webpack如何優化vue專案

技術標籤:vue webpack壓縮程式碼

前言

日常開發中,Vue框架通常都會使用Webpack進行構建,隨著專案不斷迭代,專案逐漸變得龐大,然而專案的構建速度隨之變得緩慢,於是對Webpack構建進行優化變得刻不容緩。通過適當的方法優化後,專案的構建速度提高了50%。現將相關優化方法進行總結分享。

一.優化loader配置

由於Loader對檔案的轉換操作很耗時,所以需要讓儘可能少的檔案被Loader處理。我們可以通過以下3方面優化Loader配置:(1)優化正則匹配(2)通過cacheDirectory選項開啟快取(3)通過include、exclude來減少被處理的檔案。實踐如下:

專案原配置:

{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
},

優化後配置:

{
// 1、如果專案原始碼中只有js檔案,就不要寫成/\.jsx?$/,以提升正則表示式的效能
test: /\.js$/,
// 2、babel-loader支援快取轉換出的結果,通過cacheDirectory選項開啟
loader: 'babel-loader?cacheDirectory',
// 3、只對專案根目錄下的src 目錄中的檔案採用 babel-loader
include: [resolve('src')]
},

二.優化UglifyJS外掛

webpack預設提供了UglifyJS外掛來壓縮JS程式碼,但是它使用的是單執行緒壓縮程式碼,也就是說多個js檔案需要被壓縮,它需要一個個檔案進行壓縮。所以說在正式環境打包壓縮程式碼速度非常慢(因為壓縮JS程式碼需要先把程式碼解析成用Object抽象表示的AST語法樹,再去應用各種規則分析和處理AST,導致這個過程耗時非常大)。

因此我們需要可以並行處理多個子任務,多個子任務完成後,再將結果發到主程序中,有了這個思想後,因此 ParallelUglifyPlugin 外掛就產生了,當webpack有多個JS檔案需要輸出和壓縮時候,原來會使用UglifyJS去一個個壓縮並且輸出,但是ParallelUglifyPlugin外掛則會開啟多個子程序,把對多個檔案壓縮的工作分別給多個子程序去完成,但是每個子程序還是通過UglifyJS去壓縮程式碼。無非就是變成了並行處理該壓縮了,並行處理多個子任務,效率會更加的提高。

安裝 webpack-parallel-uglify-plugin 外掛

然後在webpack.config.js 配置程式碼如下:

// 引入 ParallelUglifyPlugin 外掛const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');module.exports = {  plugins: [    // 使用 ParallelUglifyPlugin 並行壓縮輸出JS程式碼    new ParallelUglifyPlugin({      // 傳遞給 UglifyJS的引數如下:      uglifyJS: {        output: {          /*           是否輸出可讀性較強的程式碼,即會保留空格和製表符,預設為輸出,為了達到更好的壓縮效果,           可以設定為false          */          beautify: false,          /*           是否保留程式碼中的註釋,預設為保留,為了達到更好的壓縮效果,可以設定為false          */          comments: false        },        compress: {          /*           是否在UglifyJS刪除沒有用到的程式碼時輸出警告資訊,預設為輸出,可以設定為false關閉這些作用           不大的警告          */warnings:false,          /*           是否刪除程式碼中所有的console語句,預設為不刪除,開啟後,會刪除所有的console語句          */drop_console:true,          /*           是否內嵌雖然已經定義了,但是隻用到一次的變數,比如將 var x = 1; y = x, 轉換成 y = 5, 預設為不           轉換,為了達到更好的壓縮效果,可以設定為false          */collapse_vars:true,          /*           是否提取出現了多次但是沒有定義成變數去引用的靜態值,比如將 x = 'xxx'; y = 'xxx'  轉換成           var a = 'xxxx'; x = a; y = a; 預設為不轉換,為了達到更好的壓縮效果,可以設定為false          */          reduce_vars: true        }      }    }),  ]}

打包對比基本上大小能相差30%!!!!

三.減少冗餘程式碼

babel-plugin-transform-runtime 是Babel官方提供的一個外掛,作用是減少冗餘的程式碼 。 Babel在將ES6程式碼轉換成ES5程式碼時,通常需要一些由ES5編寫的輔助函式來完成新語法的實現,例如在轉換 class extent 語法時會在轉換後的 ES5 程式碼裡注入 extent 輔助函式用於實現繼承。babel-plugin-transform-runtime會將相關輔助函式進行替換成匯入語句,從而減小babel編譯出來的程式碼的檔案大小

四.DllPlugin分包

通過DllPlugin外掛分離出第三方包

  • 新建webpack.dll.conf.js

const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require("clean-webpack-plugin");

module.exports = {
entry: {
vendor: [
'vue',
'vue-router',
'vuex',
'axios',
'element-ui',
'echarts'
]
},
output: {
filename: '[name]_dll_[hash:6].js', // 產生的檔名
path: path.resolve(__dirname, '../static/dll'),
library: '[name]_dll_[hash:6]'
},
plugins: [
new CleanWebpackPlugin({
root: path.resolve(__dirname, '../static/dll'),
dry: false // 啟用刪除檔案
}),
new webpack.DllPlugin({
name: '[name]_dll_[hash:6]',
path: path.resolve(__dirname, '../static/dll', '[name].dll.manifest.json')
})
]
};
  • 修改webpack.prod.conf.js

使用add-asset-html-webpack-plugin動態新增dll.jshtml

需要注意

  1. add-asset-html-webpack-plugin要在HtmlWebpackPlugin後引入;

  2. html-webpack-plugin依賴包版本4.0.0-alpha會出個問題,新增上去的路徑會變成undefined需要是3.2.0版本

const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
...
plugins: [
// 插入dll json
new webpack.DllReferencePlugin({
context: path.join(__dirname),
manifest: require('../static/dll/vendor.dll.manifest.json')
}),
new HtmlWebpackPlugin(),
// 插入 dll js
new AddAssetHtmlPlugin([{
publicPath: config.build.assetsPublicPath + 'static/dll/', // 注入到html中的路徑
outputPath: 'static/dll/', // 輸出檔案目錄
filepath: resolve('static/dll/*.js'), // 檔案路徑
includeSourcemap: false,
typeOfAsset: "js"
}])
]

五.按需載入程式碼

通過vue寫的單頁應用時,可能會有很多的路由引入。當打包構建的時候,javascript包會變得非常大,影響載入。如果我們能把不同路由對應的元件分割成不同的程式碼塊,然後當路由被訪問的時候才載入對應的元件,這樣就更加高效了。這樣會大大提高首屏顯示的速度,但是可能其他的頁面的速度就會降下來。專案中路由按需載入(懶載入)的配置:

const Foo = () => import('./Foo.vue')
const router = new VueRouter({
routes: [
{ path: '/foo', component: Foo }
]
})

六.提取公共程式碼

如果每個頁面的程式碼都將這些公共的部分包含進去,則會造成以下問題 :• 相同的資源被重複載入,浪費使用者的流量和伺服器的成本。• 每個頁面需要載入的資源太大,導致網頁首屏載入緩慢,影響使用者體驗。 如果將多個頁面的公共程式碼抽離成單獨的檔案,就能優化以上問題 。Webpack內建了專門用於提取多個Chunk中的公共部分的外掛CommonsChunkPlugin。專案中CommonsChunkPlugin的配置:// 所有在 package.json 裡面依賴的包,都會被打包進 vendor.js 這個檔案中。

new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function(module, count) {
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
);
}
}),
// 抽取出程式碼模組的對映關係
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
}),

總結:

在現實專案中,專案上線後無疑就會要進行優化,特別是使用webpack打包後的專案,如果沒有進行優化,僅靠一般的腳手架搭建預設的配置,打包出來的專案效能堪憂,最直接體現的就是首屏載入速度,也是前端面試中經常考驗的哦,不慌,經過本文以上六種(包括但不限於)優化,打包從30分鐘,到2分鐘不到,整體還有優化空間,可以使用其他cdn等再進行優化方式,快去試試吧!

覺得本文對你有幫助?請分享給更多人

關注「入坑網際網路」加星標,提升前端技能

The End

如果你喜歡,記得關注大坑

77d319686617a6fe6b34a4e4db19572c.png

萬水千山總是情,點個 “在看” 行不行