Webpack项目优化(二)

webpack5 文档 webpack.docschina.org/concepts/#e…

十六、优化16:将npm的依赖打成公共的vendor

// ... existing code ...
optimization: {
  // ... existing optimization settings ...
  splitChunks: {
    cacheGroups: {
      vendor: {
        test: /[\\/]node_modules[\\/]/, // 匹配 node_modules 中的所有依赖
        name: 'vendor', // 输出的文件名称
        chunks: 'all', // 适用于所有类型的 chunk
      },
      minSize: 0, // 最小大小为 0,确保打包所有的 chunk
      reuseExistingChunk: true, // 重用已存在的 chunk
    },
  },
},

十七、难点亮点17: 对vendor打包的进一步优化

vendor还可以继续分类。

按需加载的vendor1分一个类型(and)

全量打包的vendor2划分一个类型(react redux)

十八、极致优化18: reuseExistingChunk复用已存在的chunk

对npm的依赖,有使用到的相同代码进行进一步复用。

遇到了什么问题: npm的依赖可能有相同的代码

解决思路: 公共部分抽离复用

怎么解决的:reuseExistingChunk 配置

十九、优化19: webpack5带来的编译优化

webpack首次打包都很慢,从头编译

利用缓存。

webpack5新版本默认是带缓存的。

编译时间:从60s=>1s

我们以前是基于webpack4的,webpack4没有这个特性,所有编译很慢

面试官追问:webpack4可以缓存吗?

可以利用插件,但是不是原生的。性能不如webpack5要好

二十、优化20:Tree shaking树摇,删除多余代码

  1. 删除没用到的模块
  2. 要用es6 module

追问?

你的webpack怎么配置tree shaking?

1.usedExports

优化(Optimization) | webpack 中文文档

2.sideEffects

Tree Shaking | webpack 中文文档

SideEffect就是手动指定告诉webpack哪些模块肯定是es6,你放心的删除没用用到的模块, 如果没使用配置sideEffect,可能有些代码删不掉。

二十一、优化21: ts编译是存在瓶颈,使用多线程来优化

Ts-loder

使用ForkTsCheckerwebpackPlugin插件来开启ts的多线程编译

module: {
  rules: [
    // ... existing rules
    {
      test: /\.(ts|tsx)$/,
      use: [
        {
          loader: 'ts-loader',
          options: {
            transpileOnly: true, // 只进行转译,不进行类型检查
            // 可能还有其他选项,但图片中未显示
          },
          exclude: /node_modules/, // 排除node_modules目录中的文件
        },
        // 可能还有其他loader,但图片中未显示
      ],
      // 可能还有其他规则配置,但图片中未显示
    },
    // ... other existing rules
  ],
  plugins: [
    // ... existing plugins
    new ForkTsCheckerWebpackPlugin({
      async: true, // 启用异步检查
      typescript: {
        configFile: './tsconfig.json', // 指定tsconfig文件
        // 可能还有其他typescript配置,但图片中未显示
      },
      // 可能还有其他插件配置,但图片中未显示
    }),
    // ... other existing plugins
  ],
  // 可能还有其他module配置,但图片中未显示
},

优化的时候,要结合speed插件,去观测具体优化的效果

Ts => 1s

多线程 =>2s

开启多线程本身就具有性能损耗

TS => 50s

多线程 => 15s

二十二、难点22: 如何选择哪些资源可以开启多线程优化性能。

比如: js、ts、代码的混淆(terser)输出。

比如css的编译,less-loader =>css-loader => stye-loader,互相有依赖不能开启多线程的优化

图片处理:可能可以 图片A=>图片A1

二十三、难点亮点23: TS类型检查优化(非常推荐说这个)

项目webpack编译过程

1.ts类型检查

2.对TS进行编译

很多项目,类型检查实际上是很消耗性能

为什么可以不进行类型检查?

因为我们本地的编辑器插件可以进行检查。

在使用 ts-loader 时,可以设置 transpileOnly: true,这样 TypeScript 只会进行转译,而不进行类型检查。类型检查可以通过 ForkTsCheckerWebpackPlugin 异步进行

{
  test: /\.(ts|tsx)$/,
  use: [
    {
      loader: 'ts-loader',
      options: {
        transpileOnly: true, // 只进行转译,不进行类型检查(注意:原文本中的“transpile0nly”应为“transpileOnly”)
        exclude: /node_modules/ // 排除node_modules目录中的文件
        // 注意:原文本中出现了“10,11”这样的数字,它们看起来像是无意义的文本或者识别错误,我在此将其忽略
      }
      // 注意:原文本中的排除路径重复了两次"/node_modules/",我保留了一个作为示例
    }
    // 注意:原文本中的use数组后面多了一个逗号,这在JavaScript对象中是无效的,我将其移除(但在提供的文本片段中由于格式问题未直接显示)
  ]
  // 注意:原文本可能是一个对象的一部分,但我没有足够的上下文来确定是否还有其他属性或键值对
}

使用ForkTsCheckerWebpackPlugin, 对ts的类型检查在单独的进程进行

plugins: [
  new ForkTsCheckerWebpackPlugin({
    async: true, // 启用异步检查
    typescript: {
      configFile: './tsconfig.json', // 指定tsconfig文件
      // 注意:原文本中的“1.,1)”看起来像是无意义的文本或者识别错误,我在此将其忽略
    }
    // 注意:原文本中的逗号、冒号和点可能由于识别问题而出现了错误的位置或格式,我已经进行了修正
  })
  // 注意:原文本中的plugins数组后面可能还有其他插件,但我没有足够的信息来确定,所以我在此保留了数组的开放格式
]

优化 tsconfig.json:

skipLibCheck:设置为 true,跳过库文件的类型检查

noEmit:在开发模式下可以设置为 true,避免生成输出文件。

incremental:启用增量编译,TypeScript 会缓存上次编译的结果。

plugins: [
  new ForkTsCheckerWebpackPlugin({
    async: true, // 启用异步检查
    typescript: {
      configFile: './tsconfig.json', // 指定tsconfig文件
      // 注意:原文本中的“1.,1)”看起来像是无意义的文本或者识别错误,我在此将其忽略
    }
    // 注意:原文本中的逗号、冒号和点可能由于识别问题而出现了错误的位置或格式,我已经进行了修正
  })
  // 注意:原文本中的plugins数组后面可能还有其他插件,但我没有足够的信息来确定,所以我在此保留了数组的
]

减少类型检查的范围:

确保只在需要的文件夹中进行类型检查,避免不必要的文件,

使用 include 和 exclude 选项来限制检査的文件范围。

二十四、优化24: 组件分包到底解决的是什么问题?

const module = await import('./cpA');

最终打包的产物 Cpa.sadasdsd.js

项目有5个页面,A、B、C、D、E

不分包,加载index.asdsadsd.js 大小500k

首屏加载500k的js

A.adsds.js 100k

b.adasd.js 100k

......

二十五、难点亮点25: webpack中loader的配置优化

反面教材:

将所有的js,包括node modules中的文件内容都进行babel的编译

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader'
      }
      // 可能还有其他规则,但图片中的文本没有提供
    ]
  }
  // 图片中的文本有一个属性"//.",但具体内容未给出,且格式不正确,我将其忽略了
  // 如果该属性是重要的,您需要根据实际上下文来补充完整的内容
};

正面教材:

const path = require('path');
 
module.exports = {
  // 图片中的文本有一个注释"//..",但具体内容未给出,且格式看起来不完整,我将其保留了原样
  // 但通常注释应该提供有意义的信息或者用于临时禁用代码,这里可能是一个占位符或者识别错误
  //..,
  module: {
    rules: [
      {
        test: /\.js$/, // 用于匹配所有的.js文件
        include: path.resolve(__dirname, 'src'), // 指定只包括src目录下的文件
        loader: 'babel-loader' // 使用babel-loader来处理匹配到的文件
        // 图片中的文本在loader属性后面有一些数字(如10, 1.1.1等),这些看起来像是无意义的文本或者识别错误
        // 我已经将它们忽略了,因为它们在JavaScript对象语法中是无效的
      }
      // 可能还有其他规则,但图片中的文本没有提供
    ]
  }
};

二十六、极致难点26: 极致优化webpack的模块解析时间

resolve:['js','jsx,'tsx']
import A from 'src/a'

推荐尽量准确引用的依赖

import A from 'src/a.js'

1.从src下面去寻找所有的文件,找a,找后缀是否有['js'jsx','ts'tsx"]中的一个,a.js

二十七、难点亮点27: DLL编译优化

类似操作系统的DLL文件

通用的,经常不变化的库react、redux

webpack.config.js(业务代码)

Webpack.dll.js(第三方库)

vendor.dll.js

// webpack.dll.config.js
const path = require('path');
const webpack = require('webpack');
 
module.exports = {
  mode: 'production',
  entry: {
    vendor: ['react', 'react-dom'] // 这里可以添加你需要的库
  },
  output: {
    path: path.resolve(__dirname, 'dll'),
    filename: '[name].dll.js',
    library: '[name]_lib' // 这个名称会在DLL中使用
  },
  plugins: [
    new webpack.DllPlugin({
      name: '[name]_lib',
      path: path.join(__dirname, 'dll', '[name]-manifest.json') // 生成的manifest文件
    })
  ]
};

dI和前面的vendor有啥区别呢?

d只编译一次,后面没用变化就不用再编译了。

二十八、优化28: js编译开启多线程

const path = require('path');
 
module.exports = {
  mode: 'production',
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'thread-loader', // 注意这里可能是'thread-loader',但图片中的文本识别有误
          options: {
            workers: 2 // 设置工作线程的数量
          }
        },
        // 这里可能还有其他配置,但图片中的文本没有提供完整信息
        // 例如,可能还有一个使用babel-loader的规则,但图片中的文本格式混乱,无法直接还原
        // 假设有一个使用babel-loader的规则,它可能看起来像这样:
        /*
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel-loader'
        }
        */
        // 由于图片中的文本没有提供这个规则的完整信息,所以我将它注释掉了
        // 如果您确实需要这个规则,请根据您的项目配置来添加它
        exclude: /node_modules/ // 这个排除规则可能属于上面的babel-loader规则,但在这里被错误地放置了
      }
      // 注意:图片中的数字(如1, 10, 11, 12, 13等)和逗号可能是识别错误或占位符,我已经根据上下文进行了适当的删除和整理
    ]
  }
};

开多线程,一定要谨慎,要配和speed插件,看是否真的提升了。

开多线程,自身消耗也不小。

二十九、细节优化29: 删除webpack的进度条显示

微乎其微的提升。

将 ProgressPlugin 从 webpack 中删除可以缩短构建时间。请注意,ProgressPlugin 可能不会为快速构建 提供太多价值,因此请权衡利弊再使用。

三十、优化30: 在webpack中避免在开发环境使用生产环境才需要的内容

  • TerserPlugin 代码压缩
  • [chunkhash]/[contenthash]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值