面试题答案
一键面试性能瓶颈原因分析
- loader使用
- 过多的loader链式调用:每个loader都会对文件进行处理,过多的loader链式调用会增加处理时间。例如,从原始CSS文件,先经过postcss-loader进行兼容性处理,再经过sass - loader处理Sass语法,最后经过css - loader和style - loader将样式注入到页面,若中间还插入不必要的loader,会延长处理流程。
- loader配置不合理:比如设置了不合理的exclude或include规则,导致不必要的文件被处理,增加工作量。如在处理CSS时,没有排除node_modules下的文件,而node_modules下很多文件并不需要处理。
- 打包策略
- 全量打包:每次打包都对整个项目的样式表进行全量处理,即使只修改了一个小的CSS文件,也会重新处理所有相关的样式依赖,浪费大量时间。
- 没有进行分包:大型项目中若不将样式表按功能或模块分包,会使单个打包文件过大,加载时间变长。例如将所有页面的样式都打包在一个CSS文件中,当页面很多时,这个文件会非常大。
- 缓存机制
- 没有合理利用缓存:Webpack默认对loader的处理结果没有很好的缓存机制,如果loader处理结果没有被缓存,每次构建都会重复处理相同的文件内容。比如sass - loader每次都重新编译相同的Sass文件,而实际上文件内容并没有改变。
优化策略
- loader使用优化
- 精简loader链:仔细检查项目中的loader配置,去除不必要的loader。例如,如果项目不需要对CSS进行特殊的预处理,可以去掉相应的预处理loader。
- 合理配置exclude和include:明确指定需要处理的文件目录,排除不需要处理的文件。比如在css - loader的配置中,可以这样设置:
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style - loader', 'css - loader'],
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/
}
]
}
};
- 打包策略优化
- 增量打包:使用webpack - incremental - build - plugin等插件实现增量打包。当文件内容没有改变时,不会重复处理,只处理修改的部分。例如在webpack配置文件中引入该插件:
const IncrementalBuildPlugin = require('webpack - incremental - build - plugin');
module.exports = {
plugins: [
new IncrementalBuildPlugin()
]
};
- **分包策略**:根据项目的模块或功能将样式表进行分包。比如将公共样式、各个页面的样式分别打包。可以使用mini - css - extract - plugin插件来实现:
const MiniCssExtractPlugin = require('mini - css - extract - plugin');
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css - loader']
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css'
})
]
};
- 缓存机制优化
- 启用loader缓存:在loader配置中开启缓存。例如在sass - loader中,可以这样设置:
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: [
'style - loader',
'css - loader',
{
loader:'sass - loader',
options: {
cacheDirectory: true
}
}
]
}
]
}
};
实际项目应用示例
假设一个电商项目,有商品列表页、商品详情页、购物车页等多个页面。
- loader优化:在项目初期,由于开发人员不熟悉,在CSS处理的loader链中加入了一个已经不再使用的自定义预处理loader。通过检查发现后将其去掉,构建时间明显缩短。同时,将所有样式文件都放在src/styles目录下,在loader配置中明确include这个目录并exclude掉node_modules,避免了不必要的文件处理。
- 打包策略优化:一开始项目采用全量打包,每次修改一个小的样式都要花费很长时间重新打包。后来引入webpack - incremental - build - plugin插件实现增量打包,只对修改的样式文件进行处理,大大提高了构建效率。并且利用mini - css - extract - plugin插件将公共样式打包成一个common.css文件,各个页面的样式分别打包,如productList.css、productDetail.css等,在页面加载时只加载需要的样式文件,提升了加载性能。
- 缓存机制优化:在使用sass - loader处理Sass文件时,开启cacheDirectory选项,使得相同的Sass文件在后续构建中不再重复编译,进一步加快了构建速度。