webpack性能优化

性能优化介绍

  • 开发环境性能优化
  • 生产环境性能优化

开发环境性能优化

  • 优化打包构建速度
  • 优化代码调试

生产环境性能优化

  • 优化打包构建速度(与开发环境的优化角度不一样)
  • 优化代码运行的性能

开发环境性能优化

HMR(hot module replacement)

HMR 被称为 模块热替换/热模块替换。
作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块),极大提升构建速度
使用:在 devServer 中配置如下

devServer:{
	contentBase:resolve(__dirname,'build'),
	compress:true,
	port:3000,
	open:true,
	// 开启 HMR 功能
	// 当修改了 webpack 配置,必须重新执行 npx webpack-dev-server
	hot:true
}

文件分为以下三种文件:
样式文件:可以使用 HMR 功能,因为 style-loader 内部实现了
JS文件:默认不能使用 HMR 功能 —> 需要修改JS代码,添加支持 HMR 功能的代码
注意:HMR 功能对JS的处理,只能处理非入口JS文件的其他文件
HTML文件:默认不能使用 HMR 功能,同时会导致问题:HTML 文件不能热更新了(不用做 HMR 功能,因为 HTML 文件只有一个,一旦改变,只有它自己变)
解决:修改 entry 入口,将 HTML 文件引入

JS文件添加支持 HMR 功能的代码如下:
只能在入口JS文件中添加,假设文件名叫 print.js

import print from './print.js'

if(module.hot){
	// 一旦 module.hot 为 true,说明开启了 HMR 功能。 ---> 让 HMR 功能代码生效
	module.hot.accept('./print.js',()=>{
		// 方法会监听 print.js 文件的变化,一旦发生变化,其他模块不会重新打包构建。
		// 会执行后面的回调函数
		print()
	})
}

开发环境下调试代码(source-map)

source-map:一种提供源代码到构建后代码映射技术(如果构建后代码出错了,通过映射可以追踪源代码错误)。
它在index.js中声明一下就可以了,如下:

devtool:'source-map'

它会有一些参数:
source-map:外部
错误代码准确信息和源代码的错误位置

inline-source-map:内联
只生成一个内联source-map

hidden-source-map:外部
错误代码错误原因,但是没有错误位置。不能追踪源代码错误,只能提示到构建后代码的错误位置

eval-source-map:内联
每一个文件都生产对应的source-map,都在eval
错误代码准确信息和源代码的错误位置

nosources-source-map:外部
错误代码准确信息,但是没有任何源代码信息

cheap-source-map:外部
错误代码准确信息和源代码的错误位置
只能精确到行

cheap-module-source-map:外部
错误代码准确信息,但是没有任何源代码信息
module会将loader的source-map加入

内联和外部的区别:1.外部生产了文件,内联没有
2.内联构建速度更快

使用场景:
开发环境:速度快,调试更友好
速度快(eval>inline>cheap>…)
eval-cheap-source-map
eval-source-map
调试更友好
source-map
cheap-module-source-map
cheap-source-map

vue 和 react脚手架默认使用的 eval-source-map

生产环境:源代码要不要隐藏?调试要不要更友好?
内联会让代码体积变大,所以在生产环境不用内联
nosources-source-map 全部隐藏
hidden-source-map 只隐藏源代码,会提示构建后代码错误信息

	一般使用 source-map /  cheap-module-source-map

oneOf

oneOf 中的 loader 只会匹配一个,提高 loader 的处理性能
注意:不能有两个配置处理同一种类型的文件
使用方法:

module.exports = {
	rules:[
		{
			oneOf:[
				// 这里面配置loader,不能有2个loader处理同一种文件
			]
		}
	]
}

缓存

  1. babel 缓存
    让第二次打包构建速度更快
    在配置 babel-loader 的配置选项中添加如下配置就行:
// 开启 babel 缓存
// 第二次构建时,会读取之前的缓存
cacheDirectory:true
  1. 文件资源缓存
    让代码上线运行缓存更好使用
    hash:每次 webpack 构建时会生成一个唯一的 hash 值。
    问题:因为js和css同时使用一个hash值,如果重新打包,会导致所有缓存失效。(可能我只改动了一个文件)
    解决:chunkhash 根据chunk生产的hash值。如果打包来源于同一个chunk,那么hash值就一样。
    问题:js和css的hash值还是一样的,因为css是在js中被引入的,所以同属于一个chunk。
    解决:contentchunk 根据文件的内容生成hash值。不同文件hash值一定不一样

    使用方法:在文件名里加hash值

// 如这样使用:
filename:'css/built.[contenthash:10].css',

tree shaking(去除无用代码)

前提:1.必须使用ES6模块化 2.开启 production 环境
作用:减少代码体积

在package.json中配置

"sideEffects": false  // 所有代码都没有副作用(都可以进行tree shaking)
// 问题:可能会把 css/ @babel / polyfill (副作用)文件干掉
// 解决:
"sideEffects":["*.css"]

code split(代码分割)

单页面一般配置单入口
多页面一般配置多入口
第一种配置:

// 单入口
entry:'./src/js/index.js'

// 多入口:有一个入口,最终输出就有一个 bundle
entry:{
	index:'./src/js/index.js',
	test:'./src/js/test.js'
}

output:{
	// [name]:取文件名
	filename:'js/[name].[contenthash:10].js'
}

第二种:
多入口优化设置,在 webpack.config.js 中配置:

// 1.可以将 node_modules 中代码单独打包一个chunk最终输出
// 2.自动分析多入口 chunk 中,有没有公共的文件。如果有会打包成单独一个chunk
optimization:{
	splitChunks:{
		chunks:'all'
	}
}

第三种:常用于单页面,并行加载,加载速度更快
通过js代码,让某个文件被单独打包成一个chunk

// import 动态导入语法:能将某个文件单独打包
import(/* webpackChunkName:'test' */'./test').then((result)=>{
	console.log(result)
}).catch(()=>{
	console.log('文件加载失败~')
})

懒加载和预加载

懒加载:当文件需要使用时才加载~
例:

// 在HTML文件中添加一个按钮
<button id="btn">点我</button>

// 在index.js入口文件中设置如下代码实现懒加载:
document.getElementById('btn').onclick = function(){
	import('./test').then((result)=>{
		console.log(result)
	})
}

只有当点击按钮时才加载 test.js 文件,实现了文件的懒加载

预加载 prefetch:会在使用前,提前加载js文件,兼容性较差
正常加载可以认为是并行加载(同一时间加载多个文件),预加载是等其他资源加载完毕,浏览器空闲了,再偷偷加载资源
实现代码如下:

// 在HTML文件中添加一个按钮
<button id="btn">点我</button>

// 在index.js入口文件中设置如下代码实现预加载:webpackPrefetch:true
document.getElementById('btn').onclick = function(){
	import(/* webpackChunkName:'test',webpackPrefetch:true */'./test').then((result)=>{
		console.log(result)
	})
}

PWA(渐进式网络开发应用程序:离线可访问)

需要用到 workbox 这个插件,先下载

npm i workbox-webpack-plugin

// 引入
const WorkboxWebpackPlugin = require('workbox-webpack-plugin')

使用:在 plugins 数组中直接配置

/*
	1.帮助 serviceworker 快速启动
	2.删除旧的 serviceworker

	生产一个 serviceworker 配置文件~
*/
new WorkboxWebpackPlugin.GenerateSW({
	clientsClaim:true,
	skipWaiting:true
})

在入口文件 index.js 中注册 serviceworker,还要处理兼容性问题

/* 
	1.eslint 不认识 window、navigator 等全局变量
		解决:需要修改 package.json 中eslintConfig 配置
		"env":{
			"browser":true //支持浏览器端全局变量	
		}

	2.serviceworker 代码必须运行在服务器上
	----> nodejs
	----> npm i serve -g , serve -s build 启动服务器,将 build 目录下所有资源作为静态资源暴露出去
*/

if('serviceWorker' in navigator){
	window.addEventListener('load',()=>{
		navigator.serviceWorker.register('./service-worker.js').then(()=>{
			console.log('sw注册成功~')
		}).catch(()=>{
			console.log('sw注册失败了~')
		})
	})
}

多进程打包

使用 thread-loader 开启多进程打包。
进程启动大概为 600ms,进程通信也有开销,只有工作消耗时间比较长,才需要多进程打包,开启需要如下配置:

{
	loader:'thread-loader',
	options:{
		workers:2  // 2个进程
	}
}

externals

在 webpack.config.js 中配置

externals:{
	// 拒绝jQuery被打包进来
	jquery:'jQuery'
}

作用:能用cdn在HTML文件中引入的,可以配置一下externals,可以提高打包速度。

dll

将库文件提前打包好,然后引入,
与externals不同在于,externals直接不打包
缺点是配置比较多

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Webpack是一个现代化的前端打包工具,它可以将多个模块打包成一个或多个静态资源文件。在项目开发过程中,随着代码规模的增大,Webpack性能优化变得尤为重要。以下是一些Webpack性能优化的方法: 1. 减少打包文件体积: - 使用Tree Shaking:通过ES6模块的静态分析,去除未使用的代码,减少打包文件体积。 - 使用Code Splitting:将代码拆分成多个小块,按需加载,减少初始加载时间。 - 压缩代码:使用UglifyJS等工具对代码进行压缩,减小文件体积。 2. 加快构建速度: - 使用缓存:通过配置缓存选项,将构建过程中的中间结果缓存起来,加快下次构建速度。 - 多进程/多实例构建:使用工具如HappyPack或thread-loader,将任务分解到多个子进程或实例中并行处理,提高构建速度。 - 使用DllPlugin:将第三方库等不经常变动的模块提前打包成静态资源,减少每次构建的时间。 3. 优化文件加载: - 使用CDN:将静态资源部署到CDN上,加快文件加载速度。 - 使用缓存策略:配置合适的缓存策略,使浏览器能够缓存静态资源,减少重复加载。 - 按需加载:使用动态import或异步组件等方式,按需加载模块,减少初始加载时间。 4. 配置优化: - 减少不必要的插件和loader:只加载必要的插件和loader,减少构建过程中的处理时间。 - 使用resolve.alias:配置别名,减少模块查找时间。 - 使用externals:将一些不需要打包的模块通过externals配置引入,减小打包体积。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值