ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue-cli 配置优化

2022-08-31 14:01:38  阅读:182  来源: 互联网

标签:preload vue cli 优化 js webpack gzip config css


本文整理了一些 vue 开发中常用 vue-cli 配置,使用的 vue-cli 版本为 3.11.0,主要内容包括:

移除 preload 与 prefetch
使用 webpack-bundle-analyzer 做打包分析
使用 terser-webpack-plugin 清除 console.log
使用 compression-webpack-plugin 开启 gzip 压缩
配置使用 CDN 方式引入资源库
自定义打包的 css/js/图片 文件名和路径
压缩图片
文末给出了完整的 vue.config.js 配置。

1.移除 preload(预载) 与 prefetch (预取)
vue 脚手架默认开启了 preload 与 prefetch,当我们项目很大时,这个就成了首屏加载的最大元凶了。

先简单了解一下 preload 与 prefetch。

preload 与 prefetch 都是一种资源预加载机制;
preload 是预先加载资源,但并不执行,只有需要时才执行它;
prefetch 是意图预获取一些资源,以备下一个导航/页面使用;
preload 的优先级高于 prefetch。
更多请参考 MDN:通过rel="preload"进行内容预加载

看看关闭 preload 与 prefetch 之前的效果:



这里我标注了 4 个部分,

1 代表当前页面的 css/js 资源;
2 代表 UI 库等资源的 css 与 main.js 中自定义的 css
3 代表 main.js 中自定的 js 与 UI 库等资源的 js
4 代表其他页面的资源
其中,2 和 3 都使用了 preload,4 使用了 prefetch。当应用的页面非常多时,会导致 4 的部分增加,以至于首屏加载的速度降低。

关闭 preload 与 prefetch

  chainWebpack: config => {
    // 移除 preload(预载) 插件
    config.plugins.delete('preload')
    // 移除 prefetch(预取) 插件
    config.plugins.delete('prefetch')
  }
关闭后的效果:



关闭前的首屏速度 11s,关闭后 1~2 秒,速度加快 10 倍...

2.使用 webpack-bundle-analyzer 做打包分析
脚手架中默认就包含有 webpack-bundle-analyzer 插件,所以直接使用即可

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
 
module.exports = {
  chainWebpack: config => {
    // npm run analyzer 时才开启
    if (process.env.npm_config_report) {
      config
        .plugin('webpack-bundle-analyzer')
        .use(BundleAnalyzerPlugin)
    }
  }
}
然后再配置 package.json 

  "scripts": {
    "analyzer": "cross-env NODE_ENV=production npm_config_report=true npm run build"
  },
在 cmd 中执行

npm run analyzer

页面效果(这里只展示左侧侧边栏)



3.使用 terser-webpack-plugin 清除 console.log
开发过程中我们往往需要 console.log 进行调试,调试完后一般也会删除或注释掉,但难免有时会忘记,所以可以使用 terser-webpack-plugin 来清除 console.log。

先安装依赖

npm install terser-webpack-plugin --save-dev

然后配置

const TerserPlugin = require('terser-webpack-plugin');
 
module.exports = {
  configureWebpack: config => {
    // 生产环境下清除 console.log
    if (process.env.NODE_ENV === 'production') {
      return {
        optimization: {
          minimizer: [
            new TerserPlugin({
              sourceMap: false,
              terserOptions: {
                compress: {
                  drop_console: true
                }
              }
            })
          ]
        }
      }
    }
  }
}

4.使用 compression-webpack-plugin 开启 gzip 压缩
开启 gzip 压缩也能极大加快页面加载速度。

先安装依赖

npm install compression-webpack-plugin --save-dev

然后配置

const CompressionPlugin = require('compression-webpack-plugin');
 
module.exports = {
  configureWebpack: config => {
    config.plugins = [
      ...config.plugins,
      // 开启 gzip 压缩
      new CompressionPlugin({
        filename: '[path][base].gz',
        algorithm: 'gzip',
        test: /\.js$|\.css$|\.html$/,
        threshold: 10240,
        minRatio: 0.8
      })
    ]
  }
}

压缩后会生成相应的 gz 文件



可以看见,压缩效果还是很明显的。

只有前端配置 gzip 是不够的,如果你使用了 nginx,还需对其进行配置

http {
 
    gzip on; # 开启 gzip 压缩
    gzip_static on; # 若存在静态 gz 文件,则使用该文件
    gzip_min_length 10k; # 设置允许压缩的页面最小字节数
    gzip_buffers 16 8k; # 设置用于处理请求压缩的缓冲区数量和大小
    gzip_comp_level 1; # 设置压缩级别 1-9,数字越大,压缩后的大小越小,也越占用CPU,花费时间越长
    # 对特定的 MIME 类型生效, 其中'text/html’被系统强制启用
    gzip_types application/javascript text/css font/ttf font/x-woff;
    gzip_vary on; # 是否在 http header中 添加 Vary:Accept-Encoding, on | off
    gzip_http_version 1.1; # 在 http/1.1 的协议下不开启压缩
}
gzip 相关配置说明可参考:Nginx gzip参数详解及常见问题

如果资源响应头中出现 Content-Encoding: gzip 则代表配置成功



同时,也能通过比较资源的实际大小和请求大小是否一致来判断是否开启了压缩。

5.配置使用 CDN 方式引入资源库
先完成配置:

  configureWebpack: config => {
    config.resolve = {
      // 使用 CDN 的包不用打包到文件中
      externals: {
        // 这里的 element-ui 是 import xx from yy 中的 yy 包名。ELEMENT 是文件导出的全局变量名字
        'element-ui': 'ELEMENT',
      },
    },
  },
  chainWebpack: config => {
    // 添加 CDN 参数到 htmlWebpackPlugin 配置中
    config.plugin('html').tap(args => {
      args[0].cdn = {
        js: [
          'https://xx.com/CDN/js/index-element-ui@2.13.0.js',
        ],
        css: [
          'https://xx.com/CDN/css/element-ui2.13.0/index.css',
        ],
      };
      return args;
    });
  },

然后在 index.html 中挂载 CDN:

<!DOCTYPE html>
<html lang="zh">
  <head>
    <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %>
    <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style">
    <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet">
    <% } %>
    <!-- 使用 CDN 加速的 JS 文件,配置在 vue.config.js 下 -->
    <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
    <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>" type="text/javascript"></script>
    <% } %>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

如果公司没有自己的 CDN,这里推荐两个比较好的:BootCDN 与 cdnjs 。

当然,使用他人的 CDN 你就要考虑安全和稳定性了,要是 CDN 突然挂了(可能性比较小)就很伤。

6.自定义打包的 css/js/图片 文件名和路径
如果你想自定义打包文件名的话,可以考虑进行以下配置。

const appVersion = require('./package.json').version;
const timestamp = new Date().getTime(); // 时间戳
 
module.exports = {
  css: {
    extract: {
      // 自定义打包的 css 文件名和路径
      chunkFilename: `assets/css/[name].[${appVersion}-${timestamp}].css`
    },
  },
  chainWebpack: config => {
    // 修改图片打包配置
    config.module
      .rule('images')
      .test(/\.(png|jpe?g|gif|webp)(\?.*)?$/)
      .use('url-loader')
      .loader('url-loader')
      .tap(options => {
        // 修改它的选项...
        options.fallback.options.name = `assets/img/[name].[${appVersion}-${timestamp}].[ext]`; // 修改文件名
        // 这是字节(Byte)限制,1KB = 1024Byte,当图片的大小小于4KB(默认值),则会被转为base64格式,打包进js文件,
        // 大于4KB,则会被打包进 img 文件夹,供链接请求获取。 
        options.limit = 1024 * 4;
        return options
      })
  },
  configureWebpack: config => {
    // 自定义打包的 js 文件名和路径
    config.output.chunkFilename = `assets/js/[name].[${appVersion}-${timestamp}].js`
  }
}

注:[name] 就是默认的 webpackChunkName。

大致效果如下:



7.压缩图片
如果需要对图片进行压缩的话可以使用以下配置。

先安装依赖

npm install image-webpack-loader --save-dev

然后配置

  chainWebpack: config => {
    // 压缩图片
    config.module
      .rule('images')
      .use('imageWebpackLoader')
      .loader('image-webpack-loader')
      .options({
        disable: process.env.NODE_ENV === 'development', // 开发环境下禁止压缩
        gifsicle: {
          interlaced: false
        }
      })
  }
但我一般不用这个压缩,这里推荐一个在线压缩网站:TinyPNG – Compress WebP, PNG and JPEG images intelligently

结尾:完整的 vue.config.js 配置
const path = require('path');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const TerserPlugin = require('terser-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
 
// 是否是开发环境 development | production
const isDevlopment = process.env.NODE_ENV === 'development';
// const appVersion = require('./package.json').version;
// const timestamp = new Date().getTime();
function resolve (dir) {
  return path.join(__dirname,  dir)
}
 
module.exports = {
  publicPath: './', // 根路径
  outputDir: 'dist', // 构建输出目录
  assetsDir: 'assets', // 静态资源目录
  lintOnSave: false, // 是否开启eslint保存检测,有效值:true || false || 'error'
  devServer: {
    open: false, // 项目运行后是否自动打开浏览器
    host: '0.0.0.0', // 既可localhost,也可ip访问
    port: 8081,
    https: false,
    hotOnly: false, // 热更新
  },
  productionSourceMap: false, // 生产环境下关闭 SourceMap
  css: {
    // extract: {
    //   // 自定义打包的 css 文件名和路径
    //   chunkFilename: `assets/css/[name].[${appVersion}-${timestamp}].css`
    // },
    sourceMap: isDevlopment // 开发环境下开启方便调试样式
  },
  chainWebpack: config => {
    // 移除 preload(预载) 插件
    config.plugins.delete('preload')
    // 移除 prefetch(预取) 插件
    config.plugins.delete('prefetch')
    // npm run analyzer 时才开启
    if (process.env.npm_config_report) {
      config
        .plugin('webpack-bundle-analyzer')
        .use(BundleAnalyzerPlugin) // 分析项目文件大小的插件
    }
    // 添加 CDN 参数到 htmlWebpackPlugin 配置中
    config.plugin('html').tap(args => {
      args[0].cdn = {
        js: [
          'https://xx.com/CDN/js/index-element-ui@2.13.0.js',
        ],
        css: [
          'https://xx.com/CDN/css/element-ui2.13.0/index.css',
        ],
      }
      return args
    })
    // 压缩图片
    // config.module
    //   .rule('images')
    //   .use('imageWebpackLoader')
    //   .loader('image-webpack-loader')
    //   .options({
    //     disable: isDevlopment, // 开发环境下禁止压缩
    //     gifsicle: {
    //       interlaced: false
    //     }
    //   })
    // 修改图片打包配置
    // config.module
    //   .rule('images')
    //   .test(/\.(png|jpe?g|gif|webp)(\?.*)?$/)
    //   .use('url-loader')
    //   .loader('url-loader')
    //   .tap(options => {
    //     // 修改它的选项...
    //     options.fallback.options.name = `assets/img/[name].[${appVersion}-${timestamp}].[ext]`; // 修改文件名
    //     // 这是字节(Byte)限制,1KB = 1024Byte,当图片的大小小于4KB(默认值),则会被转为base64格式,打包进js文件,
    //     // 大于4KB,则会被打包进 img 文件夹,供链接请求获取。 
    //     options.limit = 1024 * 4;
    //     return options
    //   })
  },
  configureWebpack: config => {
    // 自定义打包的 js 文件名和路径
    // config.output.chunkFilename = `assets/js/[name].[${appVersion}-${timestamp}].js`
    config.resolve = {
      extensions: ['.js', '.vue', '.json', '.css'],
      // 配置路径别名
      alias: {
        'vue$': 'vue/dist/vue.esm.js',
        '@': resolve('src'),
        'api': resolve('src/api'),
        'css': resolve('src/assets/css')
      },
      // 使用 CDN 的包不用打包到文件中
      externals: {
        // 这里的 element-ui 是 import xx from yy 中的 yy 包名。ELEMENT 是文件导出的全局变量名字
        'element-ui': 'ELEMENT',
      },
    },
    config.plugins = [
      ...config.plugins,
      // 开启 gzip 压缩
      new CompressionPlugin({
        filename: '[path][base].gz',
        algorithm: 'gzip',
        test: /\.js$|\.css$|\.html$/,
        threshold: 10240,
        minRatio: 0.8
      })
    ]
    // 生产环境下
    if (!isDevlopment) {
      return {
        optimization: {
          minimizer: [
            new TerserPlugin({
              sourceMap: false,
              terserOptions: {
                compress: {
                  drop_console: true // 生产环境下清除 console.log
                }
              }
            })
          ]
        }
      }
    }
  }
};

原文链接:https://blog.csdn.net/qq_39025670/article/details/110951945

 

标签:preload,vue,cli,优化,js,webpack,gzip,config,css
来源: https://www.cnblogs.com/zhenfeng95/p/16642864.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有