Webpack性能优化

本文主要探讨Webpack的性能优化策略,包括babel-loader的优化、忽略和不解析第三方库、多进程打包、热更新与自动刷新、DLL动态链接库的使用、开启production模式以及Scope Hoisting。这些方法旨在提升构建速度、减小产出体积,并利用浏览器缓存加速加载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 优化构建速度
  • 优化产出体积

WDS Webpack DevServer
HMR Hot Module Replacement
Live Reloading 自动刷新
vue:HMR
性能优化主要是对开发环境而言的,因为生产一般只构建一次

文件内容不变,计算的hash值就不变,可以利用浏览器缓存加快速度

1. 优化babel-loader

  • 适用于开发/生产环境
{
    test: /\.js$/,
    use: {
        loader: 'babel-loader',
        options: {
            // 对编译的文件缓存
            cacheDirectory: true,
        }
    },
    // 不编译node_modules
    exclude: path.resolve(__dirname, 'node_modules')
    // 或者include src下的代码
},

2. 优化第三方库如moment

  • 适用于开发/生产环境

index.js中引入了moment.js(但只需要引入中文的语言),给打包后的index.js造成了不必要的体积负担

① IgnorePlugin

  • 不引入相应代码,最终打包生成的自然也没有
const webpack = require('webpack')

plugins:[
	// 忽略moment库的文件夹./locale 不引入任何语言包,若需要使用则手动引入
	new webpack.IgnorePlugin(/\.\/locale/,/moment/)
]

② noParse

  • 不做打包,最终打包生成的有这部分代码
  • 减少打包的时间,但没有减小体积
module.exports = {
	// 不做打包的配置
	noParse: [/vue\.min\.js$/]
}
  • index.js
// 手动引入中文语言包
import 'moment/locale/zh-cn'

3. 多进程打包1(加快打包速度)

  • JS/NodeJS/Webpack都是单线程的
  • 可以开启多进程打包
  • happyPack - 和babel-loader相关
  • 开启多进程也是有开销的
const HappyPack= require('happypack')
...
{
    test: /\.js$/,
    // 将对js的处理交给id为babel的happyPack的实例
    use: ['happypack/loader?id=babel'],
    // 不编译node_modules
    exclude: path.resolve(__dirname, 'node_modules')
},

...

plugins:[
	// 创建实例
	new HappyPack({
		id: 'babel',
		loaders: ['babel-loader?cacheDirectory']
	})
]

在这里插入图片描述

4. 开启多进程2

  • webpack-parallel-uglify-plugin
const ParallelUglifyPlugin= require('webpack-parallel-uglify-plugin')

...

plugins:[
	new ParallelUglifyPlugin({
		uglifyJS: {
			beautify: false,
			comments: false // 关闭注释
		}
	})
]

自动刷新watch 热更新HMR

  • 不要用在生产环境下
module.exports = {
	// 这是webpack devServer自带的
	watch: true, // 监听 自动刷新
	watchOptions: {
		ignored: /node_modules/,
		aggregateTimeout: 300, // 监听到变化后300ms再编译
		poll: 1000, // 每隔1s看代码是否变化
	}

}

热更新配置写法2

  • css自动配置了热更新、js要手动配置

  • devServer 3.9.0

  • webpack.config.js

const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin')
const path = require('path')


moudule.exports = {
	entry: {
		// index: path.join(srcPath, 'index.js') 原先写法
		index: [
			'webpack-dev-server/client?http://localhost:8080/',
			'webpack/hot/dev-server',
			 path.join(srcPath, 'index.js')
		]
	},
	plugins: [
		new HotModuleReplacementPlugin ()
	],
	devServer:{
		hot: true
	}
}
  • index.js
if (module.hot) {
    console.log('module', module)
    // accept接受监听的范围 第一个参数是数组或字符串
    module.hot.accept(['./number'], () => {
        console.log('【不要清空counter,且重新执行number】')
        const oldNumber = document.getElementById('number')
        document.body.removeChild(oldNumber)
        number()
    })
}

5. DLL动态链接库

  • 不要用在生产环境下

  • 提高构建速度

  • React Vue代码体积大 打包速度慢

  • 版本变化不会很频繁

  • 可以预先打包一次 放在xx地方 再引用

  • DLLPlugin

  • DLLReferencePlugin

  • 版本信息
    在这里插入图片描述

生成文件

  • webpack.dll.conf.js (设在根目录下)
const path = require('path');
const webpack = require('webpack');

module.exports = {
  mode: 'development',
  entry: {
    react: [
      'react',
      'react-dom'
    ]
  },
  output: {
  	// 生成1
    filename: '[name]_[chunkhash].dll.js',
    path: path.join(__dirname, 'dist'),
    library: '_dll_[name]' // 全局变量_dll_react
  },
  plugins: [
    // 生成2
    new webpack.DllPlugin({
      name: '_dll_[name]', // 和library中全局变量一样全
      // 在根目录/dist/ 下生成 react.manifest.json文件
      path: path.join(__dirname, 'dist/[name].manifest.json')
    })
  ]
}
  • package.josn
"scripts": {
  "dll": "webpack --config webpack.dll.conf.js"
}
  • 生成1 react_hashxxx.dll.js(相关的react代码和react-dom代码被预先打包到这里)
  • 生成2 react.manifest.json (当业务代码要使用react或react-dom的某些模块,就会到这里去找索引 → 找到代码)

使用dll

  • index.html
  • 模板 打包后dist目录下的index就会去读dist中的react.dll.js
<script src="./react.dll.js"></script>
// 这样就能使用全局变量_dll_react
  • webpack.dev.conf.js 使用react.manifest.json
const webpack = require('webpack');
// 或直接const DllReferencePlugin = require('webpack/lib/DllReferencePlugin')
module.exports = {
  // ...
  plugins: [
    new webpack.DllReferencePlugin({
      manifest: require(path.resolve(__dirname_, './dist/react.manifest.json'))
    })
  ]
}
  • npm run dll一次后,再npm run dev,就不会再打包react和react-dom了

6. 开启production模式

  • 开启代码压缩
  • 对于vue、react项目,mode开启production模式,打包后的代码会剔除warning相关的代码,减小包体积,加快速度。同时vue也不用去检查错误,运行更快。
  • production模式自动做tree shaking,去除引入模块中未使用的代码
  • 注意:tree shaking只对ESM有效,对CJS无效
  • ESM是静态引入,编译时引入
  • CJS是动态引入,执行时引入
  • TS在编译时能提示出错误.
  • ESM import语句要放在top level

7. Scope Hoisting

  • 用在生产环境
  • 打包后文件只有一个IIFE(合并函数),mode:production已经默认合并
  • webpack.prod.conf.js
const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin')

plugins: [
	new ModuleConcatenationPlugin()
],
// 优先引入ES6模块的代码
resolve: {
	mainFields: ['jsnext: main', 'browser', 'main'] 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值