webpack打包优化

58 阅读3分钟

webpack打包

我们通常使用webpack-bundle-analyzer来分析打包后的文件体积,目的是为了优化应用性能。关于包大小的正常范围,并没有一个绝对的标准,因为它取决于项目的类型、规模以及目标用户的环境。但是,我们可以根据一些常见的指导原则来考虑:

  1. 初始加载包(Initial Bundle)大小:通常,我们希望初始加载的JavaScript包(通常是主chunk)在100KB到500KB之间(经过gzip压缩后)。这个范围不是绝对的,但是一个常见的参考。如果超过500KB,可能会开始影响加载性能,尤其是在移动网络或慢速网络上。
  2. 按需加载(Code Splitting) :对于大型应用,我们通常使用代码分割来按需加载不同路由或功能的代码。每个按需加载的块应该尽可能小,比如每个路由的块在500KB以下(gzip后)。
  3. 总体积:整个应用的所有资源(包括JS、CSS、图片等)的总体积,现代web应用通常控制在2MB以内,但具体取决于应用功能。

为什么要优化包体积?

  1. 加载时间:包体积直接影响下载资源所需的时间。在慢速网络上,大体积的包会导致明显的延迟,影响用户体验。
  2. 解析和执行时间:浏览器需要解析和执行JavaScript,过大的包会增加主线程的负担,导致较长的脚本执行时间,可能会引起界面卡顿。
  3. 缓存:较小的包可以更好地利用浏览器缓存,当资源更新时,用户只需要下载较小的更新包。
  4. 移动端用户:移动网络可能按流量计费,且速度较慢,减小包体积可以为他们节省流量并提升加载速度。
  5. SEO:页面加载速度是搜索引擎排名的一个因素,较快的加载速度有助于SEO。

因此,我们使用webpack-bundle-analyzer来识别包中体积较大的部分,然后通过以下方式优化:

  • 代码分割(Code Splitting):将代码拆分成多个块,按需加载。
  • tree shaking:移除未使用的代码。
  • 优化资源:压缩图片、使用更高效的库、移除重复的依赖等。
  • 使用CDN:将一些不常变动的库通过CDN引入,减少打包体积。

总之,包大小的优化目标是使应用加载更快、运行更高效,提升用户体验。

如何使用webpack-bundle-analyzer

 chainWebpack: (config) => {
    config.plugins.delete('fork-ts-checker')
    if (process.env.npm_config_report) {
      config
        .plugin('webpack-bundle-analyzer')
        .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
    }
  },

这里举例两种方式来优化包体积,主要正对第三方库

1、使用CDN

  // 在main.ts中引入对应库的cdn
      <script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script>
  
  // 在webpack中配置
  externals: {
    // 键:要外部化的模块名
    // 值:全局变量名(xlsx 库在全局暴露的变量名)
    'xlsx': 'XLSX',
    // 如果还需要其他库,可以继续添加
    // 'lodash': '_'
  },

2、使用按需加载的方式(这里以element-plus举例)

 // 安装unplugin-auto-import 和unplugin-vue-components
 // vue.config.js配置

// 1. 引入插件和解析器
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')

module.exports = {
  // ... 其他配置
  configureWebpack: {
    // ... 其他 webpack 配置
    plugins: [
      // 2. 配置 AutoImport 插件
      AutoImport({
        // 定义需要自动导入的库
        imports: ['vue', 'vue-router'],
        // 配置 ElementPlus 的解析器
        resolvers: [ElementPlusResolver()],
        // 指定生成 d.ts 文件的位置和文件名
        dts: 'src/auto-imports.d.ts',
      }),
      
      // 3. 配置 Components 插件
      Components({
        // 配置 ElementPlus 的解析器
        resolvers: [ElementPlusResolver({
          // 我们之前的配置是 importStyle: 'css',这会导入每个组件的独立 CSS 文件
          importStyle: 'css' 
        })],
        // 指定生成 d.ts 文件的位置和文件名
        dts: 'src/components.d.ts',
      }),
    ],
  },
  // ... 其他配置
}
 

这样不需要在main.ts中去手动引入element-plus 但是需要手动引入elemnt-plus中的样式

import 'element-plus/dist/index.css'

通过上面两种方式,将项目包从1.4M优化到1M内

image.png