前言:最新打包vue cli  项目时,体积尽然达到了12M,影响页面访问的速度,因此进行尝试优化,最终压缩到 668k ,效果明显。下面是优化方法。

 

一、BundleAnalyzer 

作用:展示打包图形化信息,会打开一个html页面,帮助自己分析哪些文件过大,可针对其进行优化,上线前 注释掉

 安装 webpack-bundle-analyzer 插件 

npm install webpack-bundle-analyzer --save-dev

 在 vue.config.js: 里面:

// 引入
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
 
// 展示图形化信息
chainWebpack: config => {
  config
      .plugin('webpack-bundle-analyzer')
      .use(BundleAnalyzerPlugin)
}

二、使用cdn

打包时,把vue、vuex、vue-router、axios等,换用国内的bootcdn 直接引入到根目录的index.html中。

在webpack设置中添加externals,忽略不需要打包的库。

externals: { 'vue': 'Vue', 'vue-router': 'VueRouter', 'vuex': 'Vuex', 'axios': 'axios' } 

在index.html中使用cdn引入。

 <script src="//cdn.bootcss.com/vue/2.5.2/vue.min.js"></script>
 <script src="//cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
 <script src="//cdn.bootcss.com/vuex/2.4.1/vuex.min.js"></script>
 <script src="//cdn.bootcss.com/axios/0.15.3/axios.min.js"></script>
 <script src="//cdn.bootcss.com/element-ui/2.5.4/index.js"></script>

三、组件异步加载(按需加载)

1、使用() => import()  --es6提案

{

    path: '/lock',
    name: '锁屏页',
    component: () =>
        import( /* webpackChunkName: "page" */ '@/page/lock/index'),
    meta: {
        keepAlive: true,
        isTab: false,
        isAuth: false
    }
},
{
    path: '/404',
    component: () =>
        import( /* webpackChunkName: "page1" */ '@/components/error-page/404'),
    name: '404',
    meta: {
        keepAlive: true,
        isTab: false,
        isAuth: false
    }

},

根据webpackChunkName的不同,上面2个组件,将会被分成2个块打包,最终打包之后与组件相关的js文件会分为2个

2、 require.ensure 官方推荐

const Province = r => require.ensure([], () => r(require('@/components/Province.vue')), 'chunkname1')

const Segment = r => require.ensure([], () => r(require('@/components/Segment.vue')), 'chunkname1')

const Loading = r => require.ensure([], () => r(require('@/components/Loading.vue')), 'chunkname3')

const User = r => require.ensure([], () => r(require('@/components/User.vue')), 'chunkname3')

根据 chunkame的不同, 上面的四个组件, 将会被分成3个块打包,最终打包之后与组件相关的js文件会分为3个

四、压缩代码并移除console

        安装 uglifyjs-webpack-plugin

在 vue.config.js文件引入

const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

configureWebpack: {
     optimization: {
          minimizer: [
            new UglifyJsPlugin({
              uglifyOptions: {
                compress: {
                  // warnings: false,
                  drop_console: true, //注释console
                  drop_debugger: false,
                  pure_funcs: ['console.log'] //移除console
                }
              }
            })
          ]
      }
},
     

五、gzip压缩代码  

        安装 compression-webpack-plugin 插件 

 npm install compression-webpack-plugin -D

在 vue.config.js里面: 


const CompressionWebpackPlugin = require('compression-webpack-plugin');
configureWebpack: { 
 plugins: (() => {
            let plugins = []
            if (isProduction) {
                plugins.push(new UglifyJsPlugin({ // 代码压缩
                    uglifyOptions: {
                        //生产环境自动删除console
                        compress: {
                            // warnings: false, // 若打包错误,则注释这行
                            drop_debugger: true,
                            drop_console: true,
                            pure_funcs: ['console.log']
                        }
                    },
                    sourceMap: false,
                    parallel: true
                }))

                plugins.push(new CompressionWebpackPlugin({ // gzip压缩
                    algorithm: 'gzip',
                    test: new RegExp(
                        '\\.(' + ['html', 'js', 'json', 'css'].join('|') + ')$'
                    ),
                    threshold: 10240, //对超过10k的数据压缩
                    minRatio: 0.8,
                    deleteOriginalAssets: false //不删除源文件
                }))
            }
            plugins.push(new webpack.DefinePlugin({
                "process.argv": JSON.stringify(process.argv)
            }))
            return plugins
        })()
}

六、代码分割 

在 vue.config.js里面:

configureWebpack: {
   optimization: {
            runtimeChunk: 'single',
            splitChunks: {
                chunks: 'all',
                maxInitialRequests: Infinity,
                minSize: 1000 * 60,
                cacheGroups: {
                    common: {
                        name: `chunk-common`,
                        minChunks: 2,
                        priority: 2,
                        chunks: 'initial',
                        reuseExistingChunk: true//如果当前块包含已经从主包中分离出来的模块,那么该模块将被重用,而不是生成新的模块
                    },
                    vendor: {
                        test: /[\\/]node_modules[\\/]/,
                        name(module) {
                            // 排除node_modules 然后吧 @ 替换为空 ,考虑到服务器的兼容
                            const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
                            return `${name}.${packageName.replace('@', '')}`
                        }
                    }
                }
            }
        },

}

SplitChunks插件配置选项 

chunks 选项,决定要提取哪些模块
默认是 async :只提取异步加载的模块出来打包到一个文件中。
异步加载的模块:通过 import(‘xxx’) 或 require([‘xxx’],() =>{}) 加载的模块。

initial:提取同步加载和异步加载模块;
如果 xxx 在项目中异步加载了,也同步加载了,那么 xxx 这个模块会被提取两次,分别打包到不同的文件中。
同步加载的模块:通过 import xxx 或 require(‘xxx’) 加载的模块。

all:不管异步加载还是同步加载的模块都提取出来,打包到一个文件中;

minSize 选项:规定被提取的模块在压缩前的大小最小值,单位为字节;
默认为30000,只有超过了30000字节才会被提取。

maxSize 选项:把提取出来的模块打包生成的文件大小不能超过maxSize值;
如果超过了,要对其进行分割并打包生成新的文件。
单位为字节,默认为0,表示不限制大小。

minChunks 选项:表示要被提取的模块最小被引用次数,引用次数超过或等于minChunks值,才能被提取。

maxAsyncRequests 选项:最大的按需(异步)加载次数,默认为 6;

maxInitialRequests 选项:打包后的入口文件加载时,还能同时加载js文件的数量(包括入口文件),默认为4。

优先级 :maxInitialRequests / maxAsyncRequests < maxSize < minSize;

automaticNameDelimiter 选项:打包生成的js文件名的分割符,默认为:~

name选项:打包生成 js 文件的名称;

cacheGroups 选项,核心重点,配置提取模块的方案,里面每一项代表一个提取模块的方案。
下面是 cacheGroups 每项中特有的选项,其余选项和外面一致,若 cacheGroups 每项中有,就按配置的,没有就使用外面配置的;

test 选项:用来匹配要提取的模块的资源路径或名称,值是正则或函数;

priority 选项:方案的优先级,值越大表示提取模块时优先采用此方案,默认值为0;

reuseExistingChunk 选项:true / false。
为true时,如果当前要提取的模块,在已经在打包生成的js文件中存在,则将重用该模块,而不是把当前要提取的模块打包生成新的 js 文件。

enforce选项:true / false。
为true时,忽略minSize,minChunks,maxAsyncRequests和maxInitialRequests外面选项

配置选项很多,在实际项目中使用 SplitChunks,让你更深刻理解这些配置选项。

七、prefetch 和 preload

删除无用的插件,避免加载多余的资源(如果不删除的话,则会在 index.html 里面加载 无用的 js 文件)

chainWebpack: config => {
    // 移除prefetch插件,避免加载多余的资源
    config.plugins.delete('prefetch')
    / 移除 preload 插件,避免加载多余的资源
    config.plugins.delete('preload');
}

 八、抽离 css 支持按需加载

        安装 mini-css-extract-plugin 插件

 npm install mini-css-extract-plugin -D

在 vue.config.js里面:

chainWebpack: config => {
  let miniCssExtractPlugin = new MiniCssExtractPlugin({
    filename: 'assets/[name].[hash:8].css',
    chunkFilename: 'assets/[name].[hash:8].css'
  })
  config.plugin('extract-css').use(miniCssExtractPlugin)
}

 九、图片按需加载

        安装image-webpack-loader插件

npm install image-webpack-loader -D 

在 vue.config.js里面:  

config.module.rule('images')
    .test(/\.(png|jpe?g|gif|webp)(\?.*)?$/)
    .use('image-webpack-loader')
    .loader('image-webpack-loader')
    .options({
      bypassOnDebug: true
    })
    .end()

 

Logo

前往低代码交流专区

更多推荐