今天前端妹子讓我優化項目,想無,一大早來到公司,老大已經到了,我耳機聽着謝霆鋒的歌‘活着via’,慶幸活着真好,想無,過了國慶心情是真的很好啊,歇息歇得我快廢掉了,趕忙打代碼,不打代碼出去浪對錢很差,我們仍是不泡妞了,好好把錢用來投資理財吧,泡妞太花錢了,一天能夠花你一個月的飯錢啊,心痛啊。css
一個qq消息扔過來,以前有看過webpack,只看過一點點,沒有實踐過,過了不久,有扔過來一條消息,一個連接,全都是英文的,哇靠,不知道我英文很好?哈哈,不過外國的文章是真的牛逼啊。html
4 Ways To Boost Your Vue.js App With Webpackvuejsdevelopers.com前端
我冷靜下來仔細想一想,不能直接上來就幹,咱們得有目的性的工做,首先咱們得知道哪些地方是須要咱們去優化的,哪些地方有影響到首屏加載的效果的。vue
因此,我想到有沒有什麼插件是能夠直接生成一個 report 優化報告的東西,還真有node
webpack-bundle-analyzer
這個分析插件webpack
最近基礎的用法以下:web
# NPM npm install --save-dev webpack-bundle-analyzer # Yarn yarn add -D webpack-bundle-analyzer
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { plugins: [ new BundleAnalyzerPlugin() ] }
{ analyzerMode:One of: server, static, disabled, analyzerHost {String} Default: 127.0.0.1. Host that will be used in server mode to start HTTP server. analyzerPort {Number} or auto Default: 8888. Port that will be used in server mode to start HTTP server. openAnalyzer {Boolean} Default: true. Automatically open report in default browser. generateStatsFile {Boolean} Default: false. If true, webpack stats JSON file will be generated in bundle output directory statsFilename {String} Default: stats.json. Name of webpack stats JSON file that will be generated if generateStatsFile is true. It can be either an absolute path or a path relative to a bundle output directory (which is output.path in webpack config). statsOptions null or {Object} Default: null. Options for stats.toJson() method. For example you can exclude sources of your modules from stats file with source: false option. See more options here. }
讀取輸出文件夾(一般是dist)中的stats.json文件,把該文件可視化展示的插件。便於直觀地比較各個bundle文件的大小,以達到優化性能的目的。vue-cli
1 構建完自動打開瀏覽器:默認端口爲 8888npm
new BundleAnalyzerPlugin({ analyzerMode: 'server', generateStatsFile: true, statsOptions: { source: false } })
2 使用 package.json 文件配置啓動命令element-ui
new BundleAnalyzerPlugin({ analyzerMode: 'disabled', generateStatsFile: true, statsOptions: { source: false } })
在package.json的scripts字段中加入
"bundle-report": "webpack-bundle-analyzer --port 8123 dist/stats.json"
(3)命令行中鍵入命令
npm run bundle-report
瀏覽器自動打開分析頁面:localhost:8123
咱們能夠從哪幾個方面入手去優化,咱們拋開咱們本身的項目來聊聊通常咱們如何優化項目,
這個webpack vue-cli3 已經自動給咱們作好了,咱們能夠沒必要擔憂
map文件是js文件壓縮後,文件的變量名替換對應、變量所在位置等原信息數據文件。我的理解是:對js壓縮過程的記錄,如瀏覽器支持,能夠經過map文件還原文件到未壓縮以前。
npm install image-webpack-loader --save-dev
// 壓縮圖片 chainWebpack: config => { config.module .rule('images') .use('image-webpack-loader') .loader('image-webpack-loader') .options({ bypassOnDebug: true }) .end() },
這段代碼作了兩件事:一是壓縮,二是轉Base64
能夠發如今dist/img下面的圖片少了一部分,緣由是:不超過4096字節會被轉換成Base64編碼,用require引用的也會被轉成和base64,超出這個限制則會被打包在img文件夾下。
咱們使用是以下:
4.公共代碼抽離
configureWebpack: () => ({ optimization: { splitChunks: { cacheGroups: { vendor:{ chunks:"all", test: /node_modules/, name:"vendor", minChunks: 1, maxInitialRequests: 5, minSize: 0, priority:100, }, common: { chunks:"all", test:/[\\/]src[\\/]js[\\/]/, name: "common", minChunks: 2, maxInitialRequests: 5, minSize: 0, priority:60 }, styles: { name: 'styles', test: /\.(sa|sc|c)ss$/, chunks: 'all', enforce: true, }, runtimeChunk: { name: 'manifest' } } } } }),
可是實際上vue-cli3 已經作了代碼抽離了,或許不是咱們須要的,咱們能夠作以上代碼更改。
asset size limit: The following asset(s) exceed the recommended size limit (244 KiB). This can impact web performance.
意思是這些文件大於了244kb,可使用Gzip在壓縮一次
npm i -D compression-webpack-plugin
plugins:[ new CompressionWebpackPlugin({ filename: '[path].gz[query]', algorithm: 'gzip', test: /\.js$|\.html$|\.json$|\.css/, threshold: 0, // 只有大小大於該值的資源會被處理 minRatio:0.8, // 只有壓縮率小於這個值的資源纔會被處理 deleteOriginalAssets: true // 刪除原文件 }) ],
可是實際上咱們不須要在代碼層面進行壓縮,其實咱們能夠在部署項目的時候開啓服務器的gzip壓縮。
當前咱們項目最主要的就是 element-ui 加 echarts 加 moment.js
這三個地方是最主要須要優化的地方,咱們從分析結構圖得知,moment.js 佔用很大致積,主要是因爲他的i18n文件佔用的。因此咱們在打包的時候,不須要打包i18n文件,只須要js文件就好了,咱們在vue.config.js作了一下處理,
至於element-ui 的時候,咱們可使用按需加載,當前項目是直接在 main.js 全局引入 element-ui 的所須要的組件,可是這樣有一個壞處就是,首屏加載的時候,咱們會把全部的東西都加載一遍,並且咱們的項目是二次封裝了element-ui 組件的,這樣就會致使
element-ui 的依賴文件被引入了兩次,因此咱們要作的就是把在main.js中引入的組件都遷移到各component組件下的各個文件
至於 echarts 也是很龐大的,就可佔用掉 3 M 多的帶寬了。因此這是一個大問題,也是不要在main.js裏面引入,不作全局引入,在各自使用到的當前項目的頁面再去引入,這樣能夠作到按需加載,就不會佔用首屏太多時間了。
最終優化下來是