vue打包篇-分析包数据再进行CDN配置图片文件压缩等优化

前言

vue程序代码写完了,不做任何优化,发现包有点大,为此我们需要分析打包文件中都有些什么。才能对症下药。主要是因为博主当初的服务器才1M带宽........1M

该Demo为vue3.0的~

查看包文件

  • 这个没有优化过的包

  • 首先,修改我们的 package.json 文件

  • 然后执行打包命令

npm run build

  • 我们会发现多了一个 report.html,打开他

  • 加载时长

分析

vue-cli的打包策略是将node_module中的包打包成一个chunk-vendors.js 其他的js 如assets中的打包成app.js。

现在我们需要:

1、尽量减小打包的大小,可采用CDN方式加载;

2、将包打包成压缩包并且配置好nginx压缩功能;

  • configureWebpack 通过操作对象的形式,来修改默认的webpack配置,该对象将会被 webpack-merge 合并入最终的 webpack 配置
  • chainWebpack 通过链式编程的形式,来修改默认的webpack配置
/*
 * @Author: Penk
 * @LastEditors: Penk
 * @LastEditTime: 2020-11-05 10:09:37
 * @FilePath: \penk-web-master\Vue.config.js
 */
const path = require('path');
const webpack = require('webpack');
​
function resolve(dir) {
    return path.join(__dirname, dir)
}
//config/index.js
const os = require('os');
​
// 动态设置IP,多网卡,需要配置正则表达式 如下方
// (/^192.168.1.*&/).test(alias.address)) 即表示192.168.1.1 网段
function getNetworkIp() {
    let needHost = ''; // 打开的host
    try {
        // 获得网络接口列表
        let network = os.networkInterfaces();
        for (let dev in network) {
            let iface = network[dev];
            console.log(iface)
            for (let i = 0; i < iface.length; i++) {
                let alias = iface[i];
                if (alias.family === 'IPv4' &&
                    alias.address !== '127.0.0.1' &&
                    !alias.internal &&
                    (/^192.168.1.(\d+)$/).test(alias.address)) {
                    needHost = alias.address;
                }
            }
        }
    } catch (e) {
        needHost = 'localhost';
    }
    return needHost;
}
​
// 代码压缩
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
​
// gzip压缩
const CompressionWebpackPlugin = require('compression-webpack-plugin')
​
// 是否为生产环境
const isProduction = process.env.NODE_ENV !== 'development'
​
// 本地环境是否需要使用cdn
const devNeedCdn = true;
​
// cdn链接
const cdn = {
    // cdn:模块名称和模块作用域命名(对应window里面挂载的变量名称)
    // externals中的key是用于import,
    // value表示的在全局中访问到该对象,就是window.echarts
    externals: {
        vue: 'Vue',
        vuex: 'Vuex',
        'vue-router': 'VueRouter',
        'element-ui': 'ELEMENT',
        'echarts': 'echarts',
        'moment': 'moment',
        'mavon-editor': 'MavonEditor',
        'jquery': '$',
        'tinymce': 'tinymce',
    },
    // cdn的css链接
    css: [,
        'https://unpkg.com/element-ui@2.13.2/lib/theme-chalk/index.css',
        'https://unpkg.com/element-ui@2.13.2/lib/theme-chalk/display.css',
        'https://unpkg.com/mavon-editor@2.7.7/dist/css/index.css',
        'https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.2/animate.min.css'
    ],
    // cdn的js链接
    js: [
        'https://cdn.staticfile.org/vue/2.6.11/vue.min.js',
        'https://cdn.staticfile.org/vuex/3.1.2/vuex.min.js',
        'https://cdn.staticfile.org/vue-router/3.1.5/vue-router.min.js',
        'https://unpkg.com/element-ui@2.13.2/lib/index.js',
        'https://unpkg.com/echarts@4.9.0/dist/echarts.min.js',
        'https://cdn.bootcss.com/moment.js/2.20.1/moment.min.js',
        'https://cdn.bootcss.com/moment.js/2.20.1/locale/zh-cn.js',
        'https://unpkg.com/mavon-editor@2.7.7/dist/mavon-editor.js',
        'https://cdn.bootcss.com/jquery/3.5.1/jquery.min.js',
        'https://cdn.bootcss.com/tinymce/5.2.0/tinymce.min.js'
    ]
}
​
module.exports = {
    pwa: {
        iconPaths: {
            favicon32: 'favicon.ico',
            favicon16: 'favicon.ico',
            appleTouchIcon: 'favicon.ico',
            maskIcon: 'favicon.ico',
            msTileImage: 'favicon.ico'
        }
    },
    productionSourceMap: process.env.NODE_ENV === 'production' ? false : true,
    publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
    outputDir: 'penk-web-master-dist',
    lintOnSave: false, //是否开启eslint保存检测 ,它的有效值为 true || false || 'error'\
    css: {
        extract: false
    },
    devServer: {
        open: true,
        host: getNetworkIp(),
        port: 8886,
        proxy: {
            '/server': { //这里最好有一个 /
                // target: 'http://192.168.1.150:3000', // 后台接口域名
                target: 'http://localhost:9500', // 后台接口域名
                ws: true, //如果要代理 websockets,配置这个参数
                // secure: false, // 如果是https接口,需要配置这个参数
                changeOrigin: true, //是否跨域
                pathRewrite: {
                    '^/server': ''
                }
            }
        }
    },
    chainWebpack: config => {
        // ============压缩图片 start============
        config.module
            .rule('images')
            .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
            .use('image-webpack-loader')
            .loader('image-webpack-loader')
            .options({
                bypassOnDebug: true
            })
            .end()
​
        // ============压缩图片 end============
​
        // ============注入cdn start============
        config.plugin('html').tap(args => {
            // 生产环境或本地需要cdn时,才注入cdn
            if (isProduction || devNeedCdn) args[0].cdn = cdn
            return args
        })
        // ============注入cdn start============
​
        // ============别名 start============
        config.resolve.alias
            .set('@', resolve('src'))
        // ============别名 start============
    },
    configureWebpack: config => {
​
        config.devtool = 'source-map'
​
        // 全局引入JQuery
        config.plugins.push(
            new webpack.ProvidePlugin({
                $: "jquery",
                jQuery: "jquery",
                jquery: "jquery",
                "windows.jQuery": "jquery",
                "windows.jquery": "jquery"
            })
        )
​
        // 用cdn方式引入,则构建时要忽略相关资源
        if (isProduction || devNeedCdn) config.externals = cdn.externals
​
        // 生产环境相关配置
        if (isProduction) {
            // 代码压缩
            config.plugins.push(
                new UglifyJsPlugin({
                    uglifyOptions: {
                        //生产环境自动删除console
                        compress: {
                            drop_debugger: true,
                            drop_console: true,
                            pure_funcs: ['console.log']
                        },
                        warnings: false, // 若打包错误,则注释这行
                    },
                    sourceMap: process.env.NODE_ENV === 'production' ? false : true,
                    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 // 删除原文件,不用删除也可以,会优先传递压缩文件
                })
            )
​
            // 公共代码抽离
            config.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'
                        }
                    }
                }
            }
        }
    }
}

比较

通过下图,可发现各包体积减小了

 

部分包已经采用CDN方式加载

本地加载的包,已经通过压缩的方式传递

额外Bug(图片压缩)

npm安装的image-webpack-loader会报错,哪怕你用了nrm设置了国内镜像~~~

# 使用npm安装的 image-webpack-loader在编译的时候会有问题,不信可以试试
npm install --save-dev  image-webpack-loader
npm run build
​
# 安装cnpm
npm install cnpm -g --registry=https://registry.npm.taobao.org
​
# cnpm : 无法加载文件 D:\nodejs\node_global\cnpm.ps1,因为在此系统上禁止运行脚本
# 运行cnpm会产生问题,所以需要配置一下权限
# 打开powershell
​
# 管理员授权
Start-Process powershell -Verb runAs
# 继续重新执行set-ExecutionPolicy RemoteSigned 选择 Y
​
# 安装
cnpm install --save-dev  image-webpack-loader
# 编译
npm run build

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
对于Vue项目的打包速度优化,可以尝试以下几种方法: 1. 使用CDN:将一些常用的第三方库(如VueVuex、Vue Router等)从本地打包中移除,改为通过CDN引入。这样可以减少打包体积和加快打包速度。 2. 按需引入组件:在使用UI组件库时,可以考虑按需引入组件,而不是全部引入。这可以通过babel-plugin-component等工具来实现,减少不必要的打包和编译时间。 3. 代码拆分:将大型的代码块拆分成更小的模块,利用Webpack的代码分割功能(如异步加载、按需加载)来实现懒加载。这样可以减少初始加载时间,提升用户体验。 4. 优化图片:对于项目中的图片资源,可以使用压缩工具来减小图片大小,如使用imagemin-webpack-plugin等插件进行图片压缩。 5. 缓存和持久化:合理利用浏览器缓存和服务端缓存,减少不必要的请求和加载时间。另外,可以考虑使用localStorage或IndexedDB等技术进行数据持久化,减少数据加载时间。 6. 使用Tree Shaking:通过配置Webpack的tree shaking功能,可以剔除项目中未使用的代码,减少打包体积和提升加载速度。 7. 配置合理的Webpack:根据项目需求,合理配置Webpack的各项参数,如使用cache-loader、thread-loader等插件来提升构建速度。 需要注意的是,优化策略要根据具体项目情况进行选择,不同的项目可能有不同的瓶颈和优化空间。可以通过Webpack Bundle Analyzer等工具来分析打包结果,找出优化的重点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Penk是个码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值