• alias路径查找优化

loader解析转换慢:配置loader的test、include、exclude,缩小文件解析搜索范围

  • publicPath配置cdn
  • 文件压缩:生产模式,代码自动压缩

第三方依赖多,搜索解析文件慢:
采用缓存策略,hard-source-webpack-plugin为依赖模块提供中间缓存,极大程度地提升二次构建速度。
2、

3、
压缩打包资源plugin执行慢:比如uglify-webpack-plugin,可以开启缓存、多进程。

按需加载:代码分割 & 提取公共代码

code split

主要有 2 种方式:

chunk 有两种形式:

  • initial(初始化) 是入口起点的 main chunk。此 chunk 包含为入口起点指定的所有模块及其依赖项。
  • non-initial 是可以延迟加载的块。可能会出现在使用 动态导入(dynamic imports) 或者 SplitChunksPlugin 时
  1. optimization: {
  2. splitChunks: {
  3. chunks: "all", // 所有的 chunks 代码公共的部分分离出来成为一个单独的文件
  4. },
  5. },

dll vs externals

如果我们想引用一个库,但是又不想让webpack打包,并且又不影响我们在程序中以CMD、AMD或者window/global全局等方式进行使用,那就可以通过配置Externals。这个功能主要是用在创建一个库的时候用的,但是也可以在我们项目开发中充分使用 Externals的方式,我们将这些不需要打包的静态资源从构建逻辑中剔除出去,而使用 CDN 的方式,去引用它们

有时我们希望我们通过script引入的库,如用CDN的方式引入的jquery,我们在使用时,依旧用require的方式来使用,但是却不希望webpack将它又编译进文件中

  1. <script
  2. src="https://code.jquery.com/jquery-3.1.0.js"
  3. integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
  4. crossorigin="anonymous">
  5. </script>
  6. module.exports = {
  7. //...
  8. externals: {
  9. jquery: 'jQuery'
  10. }
  11. };
  12. import $ from 'jquery';
  13. $('.my-element').animate(/* ... */);

基于externals的优化
可以详见webpack5多联邦的笔记
自动化处理等等 以及 externals的弊端

缓存

长效缓存和编译缓存

长效缓存是浏览器层面的缓存: http缓存相关知识点==> 资源有稳定的hash
Webpack通过optimization的splitChunksruntimeChunk的配置,让编译输出的文件具有稳定的hash名称,从而让浏览器能长期有效、安全的复用缓存,达到加速页面加载的效果。

编译缓存是编译时的缓存:
Webpack通过在首次编译后把结果缓存起来,在后续编译时复用缓存,从而达到加速编译的效果。

现象:

  • 代码热更新很快
  • npm run star慢
  • npm run build慢

原因:热更新的时候用了本地的缓存;其余情况都属于首次编译,没有缓存
一般的解决方案是:
1、预编译配置dll等技术,将不太变的第三方庫单独打包走单独的缓存

webpack5,要持久化什么,做了很好的回答:
持久化什么:Webpack运行时存在于内存中的那些缓存,不是loader的产物,更不是dll
实现:

  • IdleFileCachePlugin:持久化到本地磁盘
  • MemoryCachePlugin:持久化到内存

根据Webpack运行环境的不同,在dev开发时依旧使用MemoryCachePlugin,而在build时使用IdleFileCachePlugin。

Webpack5的内置缓存方案无论从性能上还是安全性上都要好于cache-loader:

  1. 性能上:由于所以被webpack处理的模块都会被缓存,缓存的覆盖率要高的多
  2. 安全上:由于cache-loader使用了基于mtime的缓存验证机制参考),导致在CI环境中缓存经常会失效,

但是Webpack5改用了基于文件内容etag的缓存验证机制,解决了这个问题。

Webpack4上常用的缓存插件:hard-source-webpack-plugin(其实就是webpack5纳入了他)
结论:DLL退出历史舞台了

Dll

事先把常用但又构建时间长的代码提前打包好(例如 react、react-dom),取个名字叫 dll。后面再打包的时候就跳过原来的未打包代码,直接用 dll。这样一来,构建时间就会缩短,提高 webpack 打包速度。

DLL 就是个另类缓存。

DLL 缓存
1.把公共代码打包为 DLL 文件存到硬盘里 1.把常用文件存到硬盘/内存里
2.第二次打包时动态链接 DLL 文件,不重新打包 2.第二次加载时直接读取缓存,不重新请求
3.打包时间缩短 3.加载时间缩短

**手动创建并管理缓存系统原理:

**

  1. 第一次请求的时候,把请求后的内容存储起来
  2. 建立一个映射表,当后续有请求时,先根据这个映射表到看看要请求的内容有没有被缓存,有的话就加载缓存,没有就走正常请求流程(也就是所谓的缓存命中问题)
  3. 命中缓存后,直接从缓存中拿取内容,交给程序处理

hard-source-webpack-plugin原理

Scope Hoisting

tree shaking

目前在webpack4 我们设置mode为production的时候已经自动开启了tree-shaking。但是要想使其生效,生成的代码必须是ES6模块

happypack多进程并发

Webpack是单线程模型的,也就是说Webpack需要一个一个地处理任务,不能同时处理多个任务。 Happy Pack 就能让Webpack做到这一点,它将任务分解给多个子进程去并发执行,子进程处理完后再将结果发送给主进程。

  1. cnpm i -D happypack
  2. // webpack.config.js
  3. rules: [
  4. {
  5. // cnpm i babel-loader @babel/core @babel/preset-env -D
  6. test: /\.jsx?$/,
  7. exclude: /node_modules/,
  8. use: [
  9. {
  10. // 一个loader对应一个id
  11. loader: "happypack/loader?id=busongBabel"
  12. }
  13. ]
  14. }
  15. ]
  16. //在plugins中增加
  17. plugins:[
  18. new HappyPack({
  19. // 用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
  20. id:'busongBabel',
  21. // 如何处理.js文件,用法和Loader配置中一样
  22. loaders:['babel-loader?cacheDirectory'],
  23. threadPool: HappyPackThreadPool,
  24. })
  25. ]