06.webpack性能优化--构建速度

  • 优化babel-loader
  • happyPack
  • IgnorePlugin
  • paralleUglifyPlugin
  • noParse
  • 自动刷新

1 happypack多进程打包

  • js单线程,开启多进程打包
  • 提高构建速度(特别是多核CPU)
javascript 复制代码
const HappyPack = require('happypack')

module.exports = smart(webpackCommonConf, {
    mode: 'production',
    output: {
        // filename: 'bundle.[contentHash:8].js',  // 打包代码时,加上 hash 戳
        filename: '[name].[contentHash:8].js', // name 即多入口时 entry 的 key
        path: distPath,
        // publicPath: 'http://cdn.abc.com'  // 修改所有静态文件 url 的前缀(如 cdn 域名),这里暂时用不到
    },
    module: {
        rules: [
            // js
            {
                test: /\.js$/,
                // 把对 .js 文件的处理转交给 id 为 babel 的 HappyPack 实例
                use: ['happypack/loader?id=babel'],
                include: srcPath,
                // exclude: /node_modules/
            },
          ]
    },
  plugins:[
     // happyPack 开启多进程打包
        new HappyPack({
            // 用唯一的标识符 id 来代表当前的 HappyPack 是用来处理一类特定的文件
            id: 'babel',
            // 如何处理 .js 文件,用法和 Loader 配置中一样
            loaders: ['babel-loader?cacheDirectory']
        }),
  ] 
    
})

关于开启多进程

  • 项目较大,打包较慢,开启多进程能提高速度
  • 项目较小,打包较快,开启多进程会降低速度(进程开销)
  • 按需使用

2. IgnorePlugin

  • 这是webpck的内置组件
  • 这个插件的作用是:忽略第三方包指定目录,让这些指定目录不要被打包进去
  • 例子:比如我们要使用moment这个第三方依赖库,该库主要是对时间进行格式化,并且支持多个国家语言
moment包打包的问题
javascript 复制代码
import moment from 'moment'
//设置语言
moment.locale('zh-cn');
let r = moment().endOf('day').fromNow();
console.log(r);

这样打印出来的就是中文的时间,因为我在使用这个API的时候,前面设置了语言类型moment.locale为中文zh-cn。但是,虽然我设置了语言为中文,但是在打包的时候,是会将所有语言都打包进去的。这样就导致包很大,打包速度又慢所以,最好能够少打包一些没用的依赖目录进去而moment的包含'./locale/'该字段路径的文件目录就是各国语言的目录,比如'./locale/zh-cn'就是中文语言

javascript 复制代码
plugins:[
  //moment这个库中,如果引用了./locale/目录的内容,就忽略掉,不会打包进去
	new Webpack.IgnorePlugin(/\.\/locale/,/moment/),
]

问题存在并解决

我们虽然按照上面的方法忽略了包含'./locale/'该字段路径的文件目录,但是也使得我们使用的时候不能显示中文语言了,所以这个时候可以手动引入中文语言的目录

javascript 复制代码
import moment from 'moment'

//设置语言

//手动引入所需要的语言包
import 'moment/locale/zh-cn';

moment.locale('zh-cn');

let r = moment().endOf('day').fromNow();

3. ParallelUglifyPlugin

webpack默认提供了UglifyJS插件来压缩JS代码,但是它使用的是单线程压缩代码,也就是说多个js文件需要被压缩,它需要一个个文件进行压缩。所以说在正式环境打包压缩代码速度非常慢(因为压缩JS代码需要先把代码解析成用Object抽象表示的AST语法树,再去应用各种规则分析和处理AST,导致这个过程耗时非常大)。使用UglifyJS压缩代码如下:

javascript 复制代码
module.exports = {
  plugins: [
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    }),
  ]
}

webpack有多个JS文件需要输出和压缩时候,原来会使用UglifyJS去一个个压缩并且输出,但是ParallelUglifyPlugin插件则会开启多个子进程,把对多个文件压缩的工作分别给多个子进程去完成,但是每个子进程还是通过UglifyJS去压缩代码。无非就是变成了并行处理该压缩了,并行处理多个子任务,效率会更加的提高

4. noParse

这是module中的一个属性,

作用:不去解析属性值代表的库的依赖

  1. 我们一般引用jquery,可以如下引用
javascript 复制代码
import jq from 'jquery'
  1. 对于上面的解析规则:当解析jq的时候,会去解析jq这个库是否有依赖其他的包
  2. 我们对类似jq这类依赖库,一般会认为不会引用其他的包(特殊除外,自行判断)。所以,对于这类不引用其他的包的库,我们在打包的时候就没有必要去解析,这样能够增加打包速率。
  3. 所以,可以在webpack的配置中增加noParse属性(以下代码只需要看module的noParse属性)
javascript 复制代码
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
	mode:'development',
	entry:'./src/index.js',
	output:{
		filename:'bundle.js',
		path:path.resolve(__dirname,'dist')
	},
	module:{
		noParse:/jquery/,//不去解析jquery中的依赖库
	},

}
相关推荐
GISer_Jing2 小时前
前端面试通关:Cesium+Three+React优化+TypeScript实战+ECharts性能方案
前端·react.js·面试
落霞的思绪3 小时前
CSS复习
前端·css
咖啡の猫5 小时前
Shell脚本-for循环应用案例
前端·chrome
百万蹄蹄向前冲7 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5818 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路8 小时前
GeoTools 读取影像元数据
前端
ssshooter9 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
你的人类朋友9 小时前
【Node.js】什么是Node.js
javascript·后端·node.js
Jerry9 小时前
Jetpack Compose 中的状态
前端
dae bal10 小时前
关于RSA和AES加密
前端·vue.js