vue-cli3.0 打包優化實踐

vue-cli3.0 打包優化實踐

  1. 配置 gzip 壓縮,打出來一個待 gzip 後綴的文件
  2. webpack-bundle-analyzer 分析
  3. webpack splitChunks, 提取出來的通用 'echarts', 'moment', 'element-ui', 'xlsx'等
  4. momentjs 優化
  5. lodash 優化
  6. 小圖片壓縮成 base64 格式
  7. xlsx 改成 xlsx.mini.min
  8. nginx http1.1 改成 http2.0
  9. SEO 優化
  10. 不常常更新模塊抽離(待更新)

優化後的分析圖-地址javascript

優化先後對比圖

parsedphp

優化前大小    優化後大小
2.7MB --> 2.11MB
複製代碼


gzipcss

優化前大小    優化後大小
882.15KB --> 685.23KB
複製代碼


Lighthousehtml

1. 配置 gzip 壓縮,打出來一個待 gzip 後綴的文件

$ npm i compression-webpack-plugin -D
複製代碼
const CompressionWebpackPlugin = require('compression-webpack-plugin');
module.exports = {
    configureWebpack: config => {
        if (process.env.NODE_ENV === 'production') {
            config.plugins.push(
                ...[
                    new CompressionWebpackPlugin({
                        filename: '[path].gz[query]',
                        algorithm: 'gzip',
                        test: /\.(js|css|html|svg)$/i,
                        threshold: 2048,
                        minRatio: 0.8
                    })
                ]
            );
        }
    }
};
複製代碼

2. webpack-bundle-analyzer 分析包

$ npm i webpack-bundle-analyzer -D

複製代碼
module.exports = {
    chainWebpack: config => {
        if (process.env.NODE_ENV === 'production') {
            // 啓動時動態建立一個html:http://localhost:8888/report.html
            // config.plugin('webpack-bundle-analyzer').use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin);
            // 生成一個靜態html,report.html
            config.plugin('webpack-report').use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, [
                {
                    analyzerMode: 'static'
                }
            ]);
        }
    }
};
複製代碼

3. webpack splitChunks, 提取出來的通用 'echarts', 'moment', 'element-ui', 'xlsx'等

// ['echarts', 'moment', 'element-ui', 'xlsx', 'chunk-vendors', 'chunk-common', 'index']
module.exports = {
    pages: {
        index: {
            // ...
            // 在這個頁面中包含的塊,默認狀況下會包含
            // 提取出來的通用 chunk 和 vendor chunk。
            chunks: ['echarts', 'moment', 'element-ui', 'xlsx', 'chunk-vendors', 'chunk-common', 'index']
        },

        chainWebpack: config => {
            if (process.env.NODE_ENV === 'production') {
                // vue-cli3.x+默認配置
                // config.optimization.splitChunks({
                // chunks: 'async',
                // minSize: 30000,
                // maxSize: 0,
                // minChunks: 1,
                // maxAsyncRequests: 6,
                // maxInitialRequests: 4,
                // automaticNameDelimiter: '~',
                // cacheGroups: {
                // vendors: {
                // name: 'chunk-vendors',
                // test: /[\\/]node_modules[\\/]/,
                // priority: -10,
                // chunks: 'initial'
                // },
                // common: {
                // name: 'chunk-common',
                // minChunks: 2,
                // priority: -20,
                // chunks: 'initial',
                // reuseExistingChunk: true
                // }
                // }
                // });
                config.optimization.splitChunks({
                    chunks: 'async',
                    minSize: 1024 * 10, // 30000,
                    maxSize: 0,
                    minChunks: 1,
                    maxAsyncRequests: 6,
                    maxInitialRequests: 4,
                    automaticNameDelimiter: '~',
                    cacheGroups: {
                        // 連接:https://juejin.cn/post/6844904105555525640
                        echarts: {
                            name: 'echarts',
                            test: /[\\/]node_modules[\\/]echarts[\\/]/,
                            minSize: 0,
                            minChunks: 1,
                            reuseExistingChunk: true,
                            chunks: 'all'
                        },
                        moment: {
                            name: 'moment',
                            test: /[\\/]node_modules[\\/]moment[\\/]/,
                            minSize: 0,
                            minChunks: 1,
                            reuseExistingChunk: true,
                            chunks: 'all'
                        },
                        'element-ui': {
                            name: 'element-ui',
                            test: /[\\/]node_modules[\\/]element-ui[\\/]/,
                            minSize: 0,
                            minChunks: 1,
                            reuseExistingChunk: true,
                            chunks: 'all'
                        },
                        xlsx: {
                            name: 'xlsx',
                            test: /[\\/]node_modules[\\/]xlsx[\\/]/,
                            minSize: 0,
                            minChunks: 1,
                            reuseExistingChunk: true,
                            chunks: 'all'
                        },

                        vendors: {
                            name: 'chunk-vendors',
                            test: /[\\/]node_modules[\\/]/,
                            priority: -10,
                            chunks: 'initial'
                        },
                        common: {
                            name: 'chunk-common',
                            minChunks: 2,
                            priority: -20,
                            chunks: 'initial',
                            reuseExistingChunk: true
                        }
                    }
                });
            }
        }
    }
}

複製代碼

4. momentjs 優化

  • 方案 1:只打包使用的文件(目前用的時這個)

vue.config.jsvue

module.exports = {
    configureWebpack: config => {
        config.plugins.push(
            ...[
                // 連接:https://juejin.cn/post/6844904105555525640
                new webpack.ContextReplacementPlugin(
                    /moment[/\\]locale$/, // 這個參數代表了咱們要改變的打包上下文
                    /zh-cn/ // 這個參數表示咱們只想打包這個正則匹配的文件
                )
            ]
        );
    }
};
複製代碼
  • 方案 2:使用 dayjs 替代 moment,代碼不用變,把 lodash 配置別名爲 dayjs

知乎上的文章: zhuanlan.zhihu.com/p/61031739?…java

module.exports = {
    chainWebpack: config => {
        config.resolve.alias
        // set第一個參數:設置的別名,第二個參數:真實的名稱(默認都是從node_modules中讀取
        .set('moment','dayjs'));
        }
};

-   方案 3: ...
複製代碼

5. lodash 優化

$ npm i lodash-webpack-plugin babel-plugin-lodash -D
複製代碼

babel.config.jsnode

module.exports = {
    presets: ['@vue/app'],
    plugins: [
        'lodash',
        [
            'component',
            {
                libraryName: 'element-ui',
                styleLibraryName: 'theme-chalk'
            }
        ]
    ]
};
複製代碼

vue.config.jswebpack

const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');

module.exports = {
    configureWebpack: config => {
        config.plugins.push(
            ...[
                new LodashModuleReplacementPlugin(),
                // 連接:https://juejin.cn/post/6844904105555525640
                new webpack.ContextReplacementPlugin(
                    /moment[/\\]locale$/, // 這個參數代表了咱們要改變的打包上下文
                    /zh-cn/ // 這個參數表示咱們只想打包這個正則匹配的文件
                )
            ]
        );
    }
};
複製代碼

6. 小圖片壓縮成 base64 格式

module.exports = {
    chainWebpack: config => {
        // 10kb之內的圖片會被打包成內聯元素
        config.module
            .rule('images')
            .use('url-loader')
            .loader('url-loader')
            .tap(options => Object.assign(options, {limit: 10240}));
    }
};
複製代碼

7. xlsx 改成 xlsx.mini.min

把全部nginx

import XLSX from 'xlsx';
複製代碼

改成如下的方式引入web

import XLSX from 'xlsx/dist/xlsx.mini.min.js';
複製代碼

8. http1.1升級http2.0

注意的點:

1. nginx version 1.9.4 以上
2. 當前配置http2基於https協議
複製代碼

nginx配置文件 nginx.conf

# http轉https
    server {
        listen 80;
        server_name yourdomain.com; #須要將yourdomain.com替換成證書綁定的域名。
        rewrite ^(.*) https://$server_name$1 permanent; #將全部HTTP請求經過rewrite指令重定向到HTTPS。
    }

    #如下屬性中,以ssl開頭的屬性表示與證書配置有關。
    server {
        # 開啓gzip
        gzip on;

        # 啓用gzip壓縮的最小文件,小於設置值的文件將不會壓縮
        gzip_min_length 1k;

        # gzip 壓縮級別,1-9,數字越大壓縮的越好,也越佔用CPU時間,後面會有詳細說明
        gzip_comp_level 9;

        # 進行壓縮的文件類型。javascript有多種形式。其中的值能夠在 mime.types 文件中找到。
        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 application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;

        # 是否在http header中添加Vary: Accept-Encoding,建議開啓
        gzip_vary on;

        # 禁用IE 6 gzip
        gzip_disable "MSIE [1-6]\.";

        # 設置壓縮所須要的緩衝區大小
        gzip_buffers 32 4k;

        # 設置gzip壓縮針對的HTTP協議版本
        gzip_http_version 1.1;
		
        # 注意這裏http2
        listen 443 ssl http2;
        #配置HTTPS的默認訪問端口爲443。
        #若是未在此處配置HTTPS的默認訪問端口,可能會形成Nginx沒法啓動。
        #若是您使用Nginx 1.15.0及以上版本,請使用listen 443 ssl代替listen 443和ssl on。
        server_name yourdomain.com; #須要將yourdomain.com替換成證書綁定的域名。
        root html;
        index index.html index.htm;
        ssl_certificate cert/cert-file-name.pem;  #須要將cert-file-name.pem替換成已上傳的證書文件的名稱。
        ssl_certificate_key cert/cert-file-name.com.key; #須要將cert-file-name.key替換成已上傳的證書密鑰文件的名稱。
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        #表示使用的加密套件的類型。
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #表示使用的TLS協議的類型。
        ssl_prefer_server_ciphers on;
        # location / {
        #     root html;  #站點目錄。
        #     index index.html index.htm;
        # }

        location / {
        	# 反向代理
            proxy_pass http://127.0.0.1:8090;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
複製代碼

http2.0 network 效果

http2

9. SEO 優化

<meta name="description" content="vue,element-ui,nodejs,express,nginx全棧管理後臺項目" />

複製代碼

10. 不常常更新模塊抽離(待更新)

待更新

相關文章
相關標籤/搜索