基于VUE-CLI3.0的npm run build打包體積優(yōu)化

項目剛發(fā)布的時候.npm run build打包出來的chunk-vendor.js體積達(dá)到了2.5m跳仿,我滴媽还绘,服務(wù)器帶寬又很低窍荧,加載實在是太慢了灿椅,然后我做了以下這些事情 (像路由懶加載什么的就不提了)浸间。

1.因為項目中使用了charts太雨,做了echarts的按需加載。

本來直接在Main.js中:

import echarts from 'echarts'
Vue.prototype.$echarts = echarts

現(xiàn)在改為在echarts組件里引入

var echarts = require('echarts/lib/echarts');
require('echarts/lib/chart/line') // 按需導(dǎo)入折線組件
require('echarts/lib/component/tooltip') // 提示組件
require('echarts/lib/component/legend') // 圖例組件

2.使用uglifyOptions去除console來減小文件大小

// 安裝uglifyjs-webpack-plugin
cnpm install uglifyjs-webpack-plugin --save-dev

// 修改vue.config.js
  configureWebpack: config => {
    if (isProduction) {
      .....
      config.plugins.push(
        new UglifyJsPlugin({
          uglifyOptions: {
            compress: {
              warnings: false,
              drop_debugger: true,
              drop_console: true,
            },
          },
          sourceMap: false,
          parallel: true,
        })       
      )
    }
  }

3.服務(wù)器開啟Gzip

// 安裝插件
cnpm i --save-dev compression-webpack-plugin

// 在vue-config.js 中加入
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const productionGzipExtensions = ['js', 'css'];
const isProduction = process.env.NODE_ENV === 'production';

.....
module.exports = {
....
  configureWebpack: config => {
    if (isProduction) {
      config.plugins.push(new CompressionWebpackPlugin({
        algorithm: 'gzip',
        test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
        threshold: 10240,
        minRatio: 0.8
      }))
    }
  }
}

需要注意的是魁蒜,這種優(yōu)化方法非常有效囊扳,大改能減少2/3的體積吩翻,但是需要服務(wù)器端也支持,因為它會在打包過程中生成.gz結(jié)尾的壓縮包锥咸,請求資源的時候就直接加載這個壓縮包里的文件了狭瞎。這里實力nginx的配置方法:
添加以下代碼:

        gzip on;
        gzip_min_length 1k;
        gzip_comp_level 9;
        gzip_types text/plain application/javascript application/x-javascript text/css application/xml 
text/javascript application/x-httpd-php image/jpeg image/gif image/png;
        gzip_vary on;
        gzip_disable "MSIE [1-6]\.";    

nginx.conf最終內(nèi)容如下:


#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    upstream njsolar  {
        server localhost:9000; #Apache
    }
    
    server {
        listen       8083;
        server_name  localhost;
        gzip on;
        gzip_min_length 1k;
        gzip_comp_level 9;
        gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
        gzip_vary on;
        gzip_disable "MSIE [1-6]\.";    
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location / {
            root   /usr/local/deploy/njsolar-ui/dist;
            index  index.html index.htm;
        }
        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}
    }
}

4.使用CDN托管

大型Web應(yīng)用對速度的追求并沒有止步于僅僅利用瀏覽器緩存,因為瀏覽器緩存始終只是為了提升二次訪問的速度搏予,對于首次訪問的加速熊锭,我們需要從網(wǎng)絡(luò)層面進(jìn)行優(yōu)化,最常見的手段就是CDN(Content Delivery Network雪侥,內(nèi)容分發(fā)網(wǎng)絡(luò))加速碗殷。通過將靜態(tài)資源緩存到離用戶很近的相同網(wǎng)絡(luò)運(yùn)營商的CDN節(jié)點上,不但能提升用戶的訪問速度速缨,還能節(jié)省服務(wù)器的帶寬消耗锌妻,降低負(fù)載。不同地區(qū)的用戶會訪問到離自己最近的相同網(wǎng)絡(luò)線路上的CDN節(jié)點旬牲,當(dāng)請求達(dá)到CDN節(jié)點后从祝,節(jié)點會判斷自己的內(nèi)容緩存是否有效,如果有效引谜,則立即響應(yīng)緩存內(nèi)容給用戶,從而加快響應(yīng)速度擎浴。如果CDN節(jié)點的緩存失效员咽,它會根據(jù)服務(wù)配置去我們的內(nèi)容源服務(wù)器獲取最新的資源響應(yīng)給用戶,并將內(nèi)容緩存下來以便響應(yīng)給后續(xù)訪問的用戶贮预。因此贝室,一個地區(qū)內(nèi)只要有一個用戶先加載資源,在CDN中建立了緩存仿吞,該地區(qū)的其他后續(xù)用戶都能因此而受益滑频。

//vue.config.js頭部插入
const CompressionWebpackPlugin = require('compression-webpack-plugin')
// 是否為生產(chǎn)環(huán)境
const isProduction = process.env.NODE_ENV !== 'development'

// 本地環(huán)境是否需要使用cdn
const devNeedCdn = true

// cdn鏈接
const cdn = {
    // cdn:模塊名稱和模塊作用域命名(對應(yīng)window里面掛載的變量名稱)
    externals: {
        vue: 'Vue',
        vuex: 'Vuex',
        'vue-router': 'VueRouter',
        'element-ui':'ELEMENT'
    },
    // cdn的css鏈接
    css: [],
    // cdn的js鏈接
    js: [
        'https://cdn.staticfile.org/vue/2.6.10/vue.min.js',
        'https://cdn.staticfile.org/vuex/3.0.1/vuex.min.js',
        'https://cdn.staticfile.org/vue-router/3.0.3/vue-router.min.js',
        'https://cdn.bootcss.com/element-ui/2.13.2/index.js'
    ]
}
//module.exports 內(nèi)插入
 chainWebpack:config =>{
    // ============注入cdn start============
      config.plugin('html').tap(args => {
        // 生產(chǎn)環(huán)境或本地需要cdn時,才注入cdn
        if (isProduction || devNeedCdn) args[0].cdn = cdn
        return args
      })
      config.plugin('webpack-bundle-analyzer').use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
      
    // ============注入cdn start============
  },

vue.config.js的最終代碼內(nèi)容如下:

// 代碼壓縮
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
// 是否為生產(chǎn)環(huán)境
const isProduction = process.env.NODE_ENV !== 'development'

// 本地環(huán)境是否需要使用cdn
const devNeedCdn = true

// cdn鏈接
const cdn = {
    // cdn:模塊名稱和模塊作用域命名(對應(yīng)window里面掛載的變量名稱)
    externals: {
        vue: 'Vue',
        vuex: 'Vuex',
        'vue-router': 'VueRouter',
        'element-ui':'ELEMENT'
    },
    // cdn的css鏈接
    css: [],
    // cdn的js鏈接
    js: [
        'https://cdn.staticfile.org/vue/2.6.10/vue.min.js',
        'https://cdn.staticfile.org/vuex/3.0.1/vuex.min.js',
        'https://cdn.staticfile.org/vue-router/3.0.3/vue-router.min.js',
        'https://cdn.bootcss.com/element-ui/2.13.2/index.js'
    ]
}
let path = require('path')
module.exports = {
  productionSourceMap: false, //優(yōu)化打包體積
  publicPath: './',
  lintOnSave: false,
  pluginOptions: {
    'style-resources-loader': {
      preProcessor: 'stylus',
      patterns: [
        path.resolve(__dirname, 'src/assets/stylus/*.styl')
        // 打開之后common.styl的加載順序有問題
      ]
    }
  },
  pwa: {
    iconPaths: { // 修改favicon favicon.ico這個路徑不對唤冈,所以不顯示favicon.ico的峡迷,需要改成正確的才會顯示
      favicon32: 'favicon.ico',
      favicon16: 'favicon.ico',
      appleTouchIcon: 'favicon.ico',
      maskIcon: 'favicon.ico',
      msTileImage: 'favicon.ico'
    }
  },
  chainWebpack:config =>{
    // ============注入cdn start============
      config.plugin('html').tap(args => {
        // 生產(chǎn)環(huán)境或本地需要cdn時,才注入cdn
        if (isProduction || devNeedCdn) args[0].cdn = cdn
        return args
      })
      config.plugin('webpack-bundle-analyzer').use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
      
    // ============注入cdn start============
  },
  configureWebpack: config => {
    // 用cdn方式引入你虹,則構(gòu)建時要忽略相關(guān)資源
    if (isProduction || devNeedCdn) config.externals = cdn.externals
    // 生產(chǎn)環(huán)境相關(guān)配置
    if (isProduction) {
      // 代碼壓縮
      config.plugins.push(
          new UglifyJsPlugin({
              uglifyOptions: {
                  //生產(chǎn)環(huán)境自動刪除console
                  compress: {
                      // warnings: false, // 若打包錯誤绘搞,則注釋這行
                      drop_debugger: true,
                      drop_console: true,
                      pure_funcs: ['console.log']
                  }
              },
              sourceMap: false,
              parallel: true
          })
      )
      // 代碼壓縮
      // ..................
      // gzip壓縮
      const productionGzipExtensions = ['html', 'js', 'css']
      config.plugins.push(
          new CompressionWebpackPlugin({
              filename: '[path].gz[query]',
              algorithm: 'gzip',
              test: new RegExp(
                  '\\.(' + productionGzipExtensions.join('|') + ')$'
              ),
              threshold: 10240, // 只有大小大于該值的資源會被處理 10240
              minRatio: 0.8, // 只有壓縮率小于這個值的資源才會被處理
              deleteOriginalAssets: false // 刪除原文件
          })
      )
    }
        // 生產(chǎn)環(huán)境相關(guān)配置

  }
}

還有個小技巧:使用webpack-bundle-analyzer能幫助你分析哪個模塊占用了你多大的空間

微信截圖_20200715162335.png

再來打個包看看現(xiàn)在多大:


0OSW))${0RSOV5`6P1983VH.png

可以看到現(xiàn)在2.5m到了1126kb,對應(yīng)的Gzip達(dá)到了405kb傅物,讓我們看看放到服務(wù)器上的效果:

3LV4POFR$KQRA_BC)$AIT%H.png

可以看到主要的chunk-vendors只有414kb夯辖,雖然加載了6s,那是因為服務(wù)器只有1M的帶寬董饰,下面的放在cdn上的文件幾乎都是秒加載的蒿褂,很棒圆米,實現(xiàn)了2.5m到400kb的突破。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末啄栓,一起剝皮案震驚了整個濱河市娄帖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谴供,老刑警劉巖块茁,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異桂肌,居然都是意外死亡数焊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門崎场,熙熙樓的掌柜王于貴愁眉苦臉地迎上來佩耳,“玉大人,你說我怎么就攤上這事谭跨「珊瘢” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵螃宙,是天一觀的道長蛮瞄。 經(jīng)常有香客問我,道長谆扎,這世上最難降的妖魔是什么挂捅? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮堂湖,結(jié)果婚禮上闲先,老公的妹妹穿的比我還像新娘。我一直安慰自己无蜂,他們只是感情好伺糠,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著斥季,像睡著了一般训桶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上泻肯,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天渊迁,我揣著相機(jī)與錄音,去河邊找鬼灶挟。 笑死琉朽,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的稚铣。 我是一名探鬼主播箱叁,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼墅垮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了耕漱?” 一聲冷哼從身側(cè)響起算色,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎螟够,沒想到半個月后灾梦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡妓笙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年若河,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寞宫。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡萧福,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辈赋,到底是詐尸還是另有隱情鲫忍,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布钥屈,位于F島的核電站悟民,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏篷就。R本人自食惡果不足惜逾雄,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望腻脏。 院中可真熱鬧,春花似錦银锻、人聲如沸永品。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鼎姐。三九已至,卻和暖如春更振,著一層夾襖步出監(jiān)牢的瞬間炕桨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工肯腕, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留献宫,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓实撒,卻偏偏與公主長得像姊途,于是被迫代替她去往敵國和親涉瘾。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容