Vue项目性能优化实践指北之打包时的优化

197 阅读3分钟

这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战

vue项目的优化分为打包时优化、代码层面的优化

打包优化

路由懒加载

{ path: '/home', name: 'home', component: import(/* webpackChunkName: "你要设置的chunk的name" */ '../page/home') }

组件懒加载

这里的 /* webpackChunkName: "[request]" */ 中的 request 表示实际解析的文件名。

const Table = () => import(/* webpackChunkName: "[request]" */ '_c/Table') 
export default { components: { Table } }

第三方CDN

首先,为什么我们要明确我们为什么要使用externals~

我们在进行开发的时候,我们有可能会使用splitChunks来进行代码的分割,但是对于一些存在着官方CDN的外部库,我们还是更期望使用CDN。

webpack已经为我们提供了externals属性,一些平时基本不会改变的基础库我们可以将它们独立出来单独加载。如此,我们可以就能利于浏览器的缓存机制,不用每次都重新加载这些库文件。

//vue.config.js 
    configureWebpack: config => { config.externals = { "element-ui": "ELEMENT" }; }, 
    chainWebpack: config =>
    { 
    const cdn = { 
            css: ["https://unpkg.com/element-ui/lib/theme-chalk/index.css"], 
            js: [ "https://unpkg.com/element-ui/lib/index.jss" ] 
     };
    }

到这里之后,不要忘记在index.html中添加cdn的引用~

<!-- 使用CDN的CSS文件 --> 
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
<link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" /> <% } %> 
<!-- 使用CDN的JS文件 --> 
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { 
%> <script type="text/javascript" src="<%= htmlWebpackPlugin.options.cdn.js[i] %>" ></script> <% } %>

在这里的CDN,我是更加推荐使用官方的CND,这样相对来说更稳定一些~

splitChunk

对于splitChunk,目前已经可以搜索到很多的使用方式了

首先,虽然我们都说它的最重要的配置项是cacheGroups,但是其它的我们也需要去了解,有的时候如果不解的话,就有可能会踩坑

  1. chunks:表示从哪些chunks里面抽取代码,除了三个可选字符串值 initial、async、all 之外,还可以通过函数来过滤所需的 chunks;
  2. minSize:表示抽取出来的文件在压缩前的最小大小,默认为 30000;
  1. maxSize:表示抽取出来的文件在压缩前的最大大小,默认为 0,表示不限制最大大小;
  2. minChunks:表示被引用次数,默认为1;
  1. maxAsyncRequests:最大的按需(异步)加载次数,默认为 5;
  2. maxInitialRequests:最大的初始化加载次数,默认为 3;
  1. automaticNameDelimiter:抽取出来的文件的自动生成名字的分割符,默认为 ~;
  2. name:抽取出来文件的名字,默认为 true,表示自动生成文件名;
  1. cacheGroups: 缓存组
//vue.config.js =>
chainWebpack(config)
config .optimization.splitChunks({ chunks: 'all', 
cacheGroups: 
{ 
    libs: { name: 'chunk-libs', test: /[\\/]node_modules[\\/]/, priority: 10, chunks: 'initial' },
    echarts: { name: 'chunk-echarts', priority: 30, test: /[\\/]node_modules[\\/]_?echarts(.*)/ }, 
    vexTable: { name: 'chunk-vexTable', priority: 30, test: /[\\/]node_modules[\\/]_?vxe-table(.*)/ }, 
    moment: { name: 'chunk-moment', priority: 30, test: /[\\/]node_modules[\\/]_?moment(.*)/ }, jsonViewer: { name: 'chunk-jsonViewer', priority: 30, test: /[\\/]node_modules[\\/]_?vue-json-viewer(.*)/ }, 
    elementUI: { name: 'chunk-elementUI', priority: 30, test: /[\\/]node_modules[\\/]_?element-ui(.*)/ }, 
    commons: { name: 'chunk-commons', test: resolve('src/components'), minChunks: 1, priority: 5, reuseExistingChunk: true } }
})

Image-webpack-loader

Image-webpack-loader 可以在打包的时候对图片进行优化

chainWebpack(config) { 
/** 忽略其它配置 ***/
config .when(process.env.NODE_ENV !== 'development', /** 忽略其它配置 ***/ config => { config.module .rule('images') .use('image-webpack-loader') .loader('image-webpack-loader') .options({ mozjpeg: { progressive: true, quality: 65 }, optipng: { enabled: false }, pngquant: { quality: [0.65, 0.9], speed: 4 }, gifsicle: { interlaced: false } // webp: { quality: 75 } }) /** 忽略其它配置 ***/ }) }

terser-webpack-plugin

wepbakc4已集成 可直接使用

config.optimization.minimizer('terser').tap((args) => { // 去除生产环境console args[0].terserOptions.compress.drop_console = true return args })

gzip

config.plugin('CompressionWebpackPlugin') .use('compression-webpack-plugin', [{ filename(asset) { asset = '[file].gz[query]'; return asset }, algorithm: 'gzip', test: productionGzipExtensions, threshold: 10240, // 只有大小大于该值的资源会被处理 10240 minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理 deleteOriginalAssets: false // 删除原文件 }])

选择使用的是 compression-webpack-plugin