webpack难点亮点(一遍就会)
webpack5 文档 webpack.docschina.org/concepts/#e...
一、优化1: 入口文件优化,提取公共的包
二、难点亮点2: splitChunks配置文件优化
less
module.exports = {
optimization: {
splitChunks: {
chunks: 'all', // 对所有类型的块进行分割
minSize: 20000, // 最小块大小,单位字节
maxSize: 0, // 最大块大小,0表示不限制
minChunks: 1, // 被引用的最小次数
maxAsyncRequests: 30, // 最大异步请求数
maxInitialRequests: 30, // 最大初始请求数
automaticNameDelimiter: '~', // 自动命名的分隔符
name: true, // 使用自动命名
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/, // 匹配 node_modules 中的模块
name: 'vendors', // 生成的块名称
chunks: 'all',
},
default: {
minChunks: 2, // 最少引用次数
priority: -20, // 优先级
reuseExistingChunk: true, // 重用已存在的块
},
},
},
},
};
三、优化3: cacheGroups缓存优化
css
a.sadas2132.js
b.adas21312.js
vendor.[hash].js
四、优化4: CDN内容分发
CDN的优化点在于,我资源没有命中缓存,需要去下载J5、css等等,才会访问CDN。
1.CDN的好处 降低服务器的压力,将压力平摊,用多台服务器顶住压力
2.用户会寻找最近的CDN服务器,减少网络延迟
业务资源和vendor资源,都可以通过cdn进行分发,提升性能
css
a.sadas2132.js
b.adas21312.js
vendor.[hash].js
五、优化5: 浏览器缓存策略优化
在我们的项目中,大部分情况是直接使用强缓存。
协商缓存和强缓存是浏览器缓存机制中的两个重要概念,主要用于提高网页加载速度和减少服务器负担。以下是它 们的简要说明:
强缓存 强缓存是指在浏览器中直接使用缓存的资源,而不需要向服务器发送请求。强缓存的实现主要依赖于 HTTP 响应头中的 Cache-Control和Expires。
Cache-Control:这个头部可以设置缓存的策略,例如:
-
max-age=3600:表示资源可以被缓存 3600 秒(1 小时)
-
no-cache:表示强制协商缓存,即每次都要向服务器验证
-
public 或 private:指定资源是否可以被共享缓存。
Expires:这个头部指定了资源的过期时间,格式为 HTTP 日期。过期后,浏览器会向服务器请求新的资源
协商缓存
协商缓存是指在强缓存过期后,浏览器向服务器发送请求,询问资源是否被修改。协商缓存的实现主要依赖于HTTP 请求头中的 If-None-Match 和 If-Modified-since。
ETag:服务器在响应中返回的一个唯一标识符,表示资源的版本。浏览器在后续请求中会将这个标识符放在 If-None-Match 请求头中,服务器会根据这个标识符判断资源是否被修改。
Last-Modified: 服务器在响应中返回的资源最后修改时间。浏览器在后续请求中会将这个时间放在 If-Modified-since 请求头中,服务器会根据这个时间判断资源是否被修改。
总结
强缓存:直接使用缓存,不向服务器请求,依赖于Cache-Control和 Expires 。
协商缓存:在强缓存过期后,向服务器请求验证资源是否被修改,依赖于 ETag 和 Last-Modified 这两种缓存机制可以有效地减少网络请求,提高网页加载速度。
六、优化6: GZIP资源压缩优化
Js格式文件 => GZIP 格式
- 文本文件:对于纯文本文件(如 HTML、CSS、JavaScript),GZIP 通常可以实现 60% 到 80% 的压缩率。这意味着文件大小可以减少到原来的 20% 到 40% 左右。
- 图片文件:对于图像文件(如 JPEG、PNG),GZIP 的效果通常不明显,因为这些格式已经经过压缩。GZIP 可提高 5% 到 10% 的压缩率。
- 其他文件类型:对于某些类型的文件(如 XML、JSON、CSV),GZIP 也能提供良好的压缩效果,通常在 50% 到 90% 之间。
补充答案:GZIP 是由 webpack 打包生成的。
前端打包出来给后台的是 JS、CSS 的原始文件。
GZIP 一般是 CDN 去做,CDN 去配置,自动进行 GZIP 压缩。
前端 => 上传 aaa.js
=> 服务器 => 上传 CDN => CDN 将 js 转成 GZIP。
用户访问 => CDN => 返回 aaa.gzip
=> 浏览器解压后 => aaa.js
七、极致优化7: babel插件包体积优化
css
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: ["> 0.25%", "not dead"]
}
}
]
],
plugins: [
'@babel/plugin-transform-runtime'
]
};
Bable-core
Corejs
pollify
javascript
JavaScript Object.assign() // es6新增的语法 => es5
a.js => a.xxxads.js (corejs assign)
b.js => b.adsaasdsad.js (corejs assign)
plugin-transform-runtime 找到我们项目中通用的corejs中的方法,放在公共部分。
八、难点8: hash粒度控制缓存优化
1.Hash
2.chunkhash 1%(基于整个chunk ex:一个组件分包)
3.contenthash 99%(基于文件 粒度最细致)
没有场景,你要强行编造场景
九、优化9: 将CSS进行单独抽离
js的内容变化,不会影响css文件,也不会影响css的hash,css可以很好的利用缓存
javascript
// webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: './src/index.js', // 入口文件
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'), // 输出文件的路径
},
module: {
rules: [
{
test: /\.css$/, // 匹配 CSS 文件
use: [
MiniCssExtractPlugin.loader,
'css-loader', // 处理 CSS 文件
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: '[id].css', // 输出的 chunk CSS 文件名
chunkFilename:'[id].css',//处理的chunk 文件名
}),
],
};
十、难点和亮点10: sourcemap调试优化
在 Webpack 中,Source Map 是一种用于调试的工具,它可以将编译后的代码映射回原始源代码。不同的 Source Map 配置选项会影响生成的 Source Map 的质量、大小和性能。以下是一些常见的 Source Map 配置选项及其区别:
1.source-map
- 描述:生成完整的 Source Map 文件,适合生产环境。
- 优点:提供完整的映射,便于调试。
- 缺点:构建速度较慢,生成的文件较大,
2.inline-source-map
- 描述:将 Source Map 作为 Data URL 嵌入到生成的文件中。
- 优点:方便调试,无需额外的请求来获取 Source Map。
- 缺点:生成的文件体积较大,适合开发环境。
3.eval-source-map
- 描述:使用 eval()包妻每个模块的代码,并生成 Source Map.
- 优点:构建速度快,适合开发环境。
- 缺点:生成的 Source Map 不够完整,可能会影响性能。
4.cheap-source-map
- 描述:生成较小的 Source Map,不包含列映射。
- 优点:构建速度快,适合开发环境。
- 缺点:不支持列映射,调试时可能不够精确。
5.cheap-module-source-map
- 描述:与 cheap-source-map 类似,但支持对loader的 Source Map 进行映射
- 优点:适合开发环境,构建速度快,
- 缺点:同样不支持列映射。
6. hidden-source-map
- 描述:生成 Source Map,但不在浏览器中暴露。
- 优点:适合生产环境,可以在调试时使用,但不暴露给用户。
- 缺点:调试时需要手动加载 Source Map.
7. nosources-source-map 描述:生成 Source Map,但不包含源代码。
- 优点:适合生产环境,保护源代码。
- 缺点:调试时无法查看源代码。
总结
选择合适的 Source Map 配置取决于您的开发和生产需求。 通常在开发环境中使用 eval-source-map 或 inline-source-map ,而在生产环境中使用 source-map 或 hidden-source-map 。根据项目的需求和性能 考虑,您可以选择最适合的配置,
十一、优化11: 监测webpack编译速度和性能
性能优化的前提: 我得先知道哪里慢?不是凭感觉优化。
ini
// 性能监控
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
const smp = new SpeedMeasurePlugin();
// 生成配置
const config = smp.wrap(configFactory('production'));
十二、难点亮点12: 优化js压缩混淆速度 terserPlugin
7s => 1.5s
1.开启多线程任务并行
2.AST抽象语法树进行了优化和复用
javascript
// webpack.config.js
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
mode: 'production', // 设置为生产模式
entry: './src/index.js', // 入口文件
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'), // 输出文件的路径
},
optimization: {
minimize: true, // 启用压缩
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true, // 删除 console.Log
},
comments: false, // 不保留注释
},
extractComments: false, // 不提取注释到单独文件
}),
],
},
};
十三、优化13: SWC提升js、ts的编译性能
SWC(Speedy web Compiler)之所以快速,主要有以下几个原因:
1.Rust 编写:SWC 是用 Rust 编写的,Rust 是一种高性能的系统编程语言,具有优秀的内存管理和并发性能。这使得 SWC 在执行速度上优于许多用 JavaScript 或其他语言编写的编译器。
2.井行处理:SWC 支持并行处理多个文件,这意味着可以同时编译多个模块,从而显著提高构建速度,尤其是在大型项目中。
3.高效的 AST(抽象语法树)处理:SWC 在编译过程中使用高效的 AST 处理,能够快速分析和转换代码结构, 减少不必要的操作。
4.优化的编译流程:SWC 采用了优化的编译流程,能够快速进行语法分析、转换和生成代码,减少了编译过程中的开销。
5.增量编译:SWC 支持增量编译,只编译发生变化的文件,而不是每次都重新编译整个项目,这样可以大幅度减少构建时间。
6.现代特性支持:SWC 支持现代 JavaScript 和 TypeScript 特性,能够高效处理新语法,避免了对旧特性的兼容性处理,从而提高了编译速度,
通过这些设计和实现,SWC能够在保持高效性能的同时,提供快速的编译体验,适合用于现代前端开发中的构建工身
javascript
module.exports = {
mode: 'development', // 设置为开发模式
entry: './src/index.ts', // 入口文件
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'), // 输出文件的路径
},
resolve: {
extensions: ['.ts', '.js'], // 解析文件扩展名
},
module: {
rules: [
{
test: /\.tsx?$/, // 匹配 .ts 和 .tsx 文件
exclude: /node_modules/, // 排除 node_modules 目录
use: {
loader: 'swc-loader',
options: {
jsc: {
parser: {
syntax: 'typescript', // 使用 TypeScript 解析
tsx: true, // 支持 TSX
},
transform: {
decoratorMetadata: true, // 启用装饰器元数据
},
},
},
},
},
],
},
};
性能提升相比babel提升了 几倍到10倍。
十四、难点解决思维14: 分析包体积,查找项目瓶颈
ini
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
包体积的优化思路: 找主要矛盾。
十五、优化15:webpack5的原生runtime chunk优化
css
optimization: {
runtimeChunk: {
name: 'runtime', // 设置 runtime chunk 的名称
},
}
runtime.js是webpack的运行上下文。 面试吹:10k=>5k 原始包体积
优化后: