webpack5 优化构建速度

下面会以这些方面来说明如何 优化构建速度

  1. 优化babel-loader
    • 使用includeexclude来缩小查找范围
    • 使用cacheDirectory来设置缓存
  2. 避免引入无用的模块:webpack.IgnorePlugin
  3. 避免重复打包:module.noParse
  4. 开启多进程打包:happypack
  5. 多进程压缩jswebpack-parallel-uglify-plugin
  6. 自动更新和热更新(仅适合开发环境):watch(devServer自动开启)、HotModuleReplacementPlugin

优化babel-loader

在遇到浏览器不识别的es6代码时,我们往往借助babel-loader去解译成ES5, 当有多个模块引用时,这个解析时间是比较长的,所以可以采用以下方式来减少解析的时间:

  1. 开启缓存,在第2次编译时,直接使用缓存,不用重新编译,缓存一般只适用于开发环境
  2. 使用includeexclude适当缩小loader的适用范围,让其更快找到要解析的文件,开发和生产环境皆适用
  module: {
    rules: [
      {
        test: /\.js$/,
        use: ['babel-loader?cacheDirectory'], // 1. 开启缓存
        include: srcPath, // 2. 缩小适用范围(使用include或exclude)
        exclude: /node_modules/
        }
    ]
  }

IgnorePlugin 避免引入无用的模块

IgnorePlugin可以用来忽略某些库中我们不需要引入的部分,比如moment包中的多国语言包,下面以moment库为例来说明如何使用

  1. 安装: npm i momnet -D
  2. index.js入口文件中,引入moment,可以看到它的体积很大,有290K,压缩后也要72k(计算包大小,可安装vscodeimport cost插件查看)
    moment包大小
// index.js
import moment from 'moment'
console.log(moment.each);
moment.locale('zh-cn');  // 设置为中文
const date = moment().format('LL');   // 2021年6月29日
console.log(date);

moment库会默认引入所有语言的代码,所以会导致代码很大,在实际开发中,其实我们一般只需要中文,或者中英两个语言的代码,这时就可以使用IgnorePlugin来优化,避免引入其他无用语言的代码

  1. 在不设置IgnorePlugin时,index打包大小295k

    image.png

  2. 设置IgnorePlugin

// webpack.prod.js或webpack.common.js都可以
const webpack = require('webpack')
const prodConfig = {
  plugins: [
    // webpack4写法
    // new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)

    // webpack5写法
    new webpack.IgnorePlugin({
      resourceRegExp: /^\.\/locale$/,   // 忽略content设置的库中的某个文件夹
      contextRegExp: /moment$/, // 要被忽略某部分内容的库
    })
  ]
}
  1. 因为忽略了moment的所有语言包,所以在index.js中要手动引入想要的语言包(这点比较麻烦,但相较性能来说值得做),比如中文
import moment from 'moment'
// 动态引入中文语言包
import 'moment/locale/zh-cn'
console.log(moment.each);
moment.locale('zh-cn');  // 设置语言为中文
const date = moment().format('LL');   // 2021年6月29日
console.log(date);
  1. 此时再打包,可以看到index打包后的体积变为64k,小了230k,所以性能是提升了很多的
    使用IgnorePlugin的moment包

noParse

noParse是用来过滤不需要解析的模块,比如jquery,lodash之类的,这些库一般不会再引入其它库,所以不需要webpack去解析其依赖,也不用打包,只是直接引用即可
noParsemodule的一个配置:

module: {
  noParse: /jquery|lodash/,
}

IgnorePluginnoParse的区别:

  • IgnorePlugin是不引入指定库的部分内容,会减少打包的体积
  • noParse是只引入库,但不对其进行webpack解析依赖和构建,包的体积不会减少,但打包速度会提升
  • 两者都可以在开发和生产环境中使用

happyPack 多进程打包

因为js是单线程的,如果引用的模块很多,且模块间引用的层级很深,那么webpack在递归解析依赖时,速度就会很慢。而使用happyPack可以开启多进程打包,会提高构建速度
它在开发或者生产环境都可以使用,不过对于小项目,使用这个优化空间不大,且开启进程可能消耗性能会更多;在大项目时,才会有较多的优化空间

  • 安装:npm i happypack -D
  • 配置:
// wepback.common.js 或webpack.prod.js 
const HappyPack = require('happypack')
// 将原来babel的配置改下,改为使用happypack多进程打包
module: {
    rules: [
      {
        test: /\.js$/,
        // use: ['babel-loader?cacheDirectory'],
        // 改为使用 happypack打包
        use: ['happypack/loader?id=babel'], // 这个id是自定义命名的,要跟插件中id对应 
        include: srcPath
      }
  ]
},
plugins: [
  new HappyPack({
      id: 'babel', // 唯一标识符
      // 使用的loader配置改写到happypack的配置项中
      use: ['babel-loader']
    })
  ]

parallelUglifyPlugin 多进程压缩js

适用生产环境

  • 安装:npm i webpack-parallel-uglify-plugin -D
  • 配置:
// webpack.prod.js
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')

plugins: [
  new ParallelUglifyPlugin({
      // 压缩js的一些配置
      uglifyJS: {
        output: {
          beautify: false,  // 不需要格式化,以最紧凑的方式输出
          comments: false // 删除注释
        },
        warnings: false, // 删除未使用一些代码时引起的警告
        compress: {
          drop_console: true, // 删除所有console.log
          // 是否内嵌虽定义,但只使用了一次的变量
          // 比如var x = 2, y = 10, z = x + y 变成 z = 12
          collapse_vars: true,
          // 提出多次出现但没定义的变量,将其变成静态值;
          // 比如x = 'xx', y = 'xx' 变成 var a = 'xx', x = a, y = a 
          reduce_vars: true 
        }
      }
    })
  ]

多进程使用总结:

  • 项目大时,打包较慢时,我们才考虑开启多进程来提高速度
  • 项目较小时,本身打包就比较快,没必要开启多进程,因为进程开启、销毁、通信,本身就有一定的性能消耗,在项目小时,有可能使用多进程反而会降低打包速度

自动刷新

在开发环境下,一般配置了devServer会默认开启自动刷新页面的功能,即watch: true,不需要我们手动再配置

// webpack.dev.js
// watch: true, //相当于默认开启watch
devServer: {
    port: 8080,
    // 设置代理
    proxy: {
      // 将本地 /api2/xxx 代理到 localhost:6666/xxx,通常用这个,/api2仅作为代理转发的标识
      '/api2': {
          target: 'http://localhost:3000',
          changeOrigin: true,
          pathRewrite: {
              '/api2': ''
          }
      },
      hot: true, // 热重载
      open: true
    }
  },

热更新

  • 自动刷新
    是指在修改模块内存时,浏览器会自动刷新页面来更新视图内容,是整个页面刷新,速度较慢;刷新页面还会导致临时状态丢失(比如表单内容)
  • 热更新
    是在不刷新页面的情况下,使新代码生效,整个网面不会刷新,状态也不会丢失

热更新配置:

// webpack.dev.js
const webpack = require('webpack')
module.exports = {
  target: 'web',
  plugins: [
    new webpack.HotModuleReplacementPlugin({})
  ]
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容