面试题答案
一键面试可能出现性能瓶颈的点
- 资源加载数量过多:项目中大量的图片和字体文件同时加载,导致请求数量庞大,增加了浏览器的负担。
- 文件体积过大:未经过压缩处理的图片和字体文件,体积过大,传输时间长,影响页面加载速度。
- 加载时机不当:在页面初始渲染时就加载所有图片和字体,而不是按需加载,尤其是对于首屏渲染无关的资源。
- Webpack配置不合理:如图片和字体的loader配置不当,没有启用合适的优化选项,或者没有正确设置缓存策略。
- 构建流程复杂:不必要的中间转换过程或重复的处理步骤,增加了构建时间。
优化策略
- Webpack配置调整
- 图片加载优化
- 使用image - webpack - loader:在
webpack.config.js
中配置该loader,对图片进行压缩。例如:
- 使用image - webpack - loader:在
- 图片加载优化
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file - loader',
options: {
name: 'images/[name].[ext]'
}
},
{
loader: 'image - webpack - loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: false
},
pngquant: {
quality: [0.65, 0.90],
speed: 4
},
gifsicle: {
interlaced: false
},
// the webp option will enable WEBP
webp: {
quality: 75
}
}
}
]
}
]
}
};
- **设置图片的加载方式**:对于较小的图片,可以使用`url - loader`将其转换为Base64编码,减少请求数。当图片大小超过一定阈值时,再使用`file - loader`。
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url - loader',
options: {
limit: 8192, // 8kb,小于该大小转换为Base64
name: 'images/[name].[ext]'
}
}
]
}
]
}
};
- **字体加载优化**
- **字体格式处理**:使用多种字体格式(如`woff2`、`woff`、`ttf`、`eot`、`svg`)以兼容不同浏览器。在`webpack.config.js`中配置:
module.exports = {
module: {
rules: [
{
test: /\.(woff|woff2|eot|ttf|otf|svg)$/,
use: [
{
loader: 'file - loader',
options: {
name: 'fonts/[name].[ext]'
}
}
]
}
]
}
};
- **字体子集化**:对于中文字体,通常体积较大,可以使用工具(如`fonttools`)进行字体子集化,只保留项目中实际用到的字符,减小字体文件体积。
2. 插件使用
- 使用webpack - bundle - analyzer插件:安装并在webpack.config.js
中配置该插件,分析打包后的文件体积分布,找出体积过大的图片或字体文件。
const BundleAnalyzerPlugin = require('webpack - bundle - analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
};
- **使用OptimizeCSSAssetsPlugin**:该插件可以优化CSS中引入的图片和字体资源,进一步压缩文件体积。
const OptimizeCSSAssetsPlugin = require('optimize - css - assets - plugin');
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style - loader',
'css - loader'
]
}
]
},
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin({})
]
}
};
- 构建流程优化
- 按需加载:对于图片,使用
import()
语法实现按需加载,特别是对于非首屏图片。例如在Vue项目中:
- 按需加载:对于图片,使用
<template>
<div>
<button @click="loadImage">加载图片</button>
<img v - if="imageUrl" :src="imageUrl" alt="">
</div>
</template>
<script>
export default {
data() {
return {
imageUrl: null
};
},
methods: {
async loadImage() {
const { default: image } = await import('./path/to/image.jpg');
this.imageUrl = image;
}
}
};
</script>
- **缓存策略**:设置合理的缓存策略,对于图片和字体资源,使用长缓存。在`webpack.config.js`中配置`output.publicPath`和`html - webpack - plugin`的`hash`选项。
module.exports = {
output: {
publicPath: '/your - cdn - url/',
filename: 'js/[name].[contenthash].js'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
hash: true
})
]
};
- **并行构建**:使用`parallel - webpack`插件,在多核CPU环境下并行处理图片和字体的打包任务,加快构建速度。安装并在`webpack.config.js`中配置:
const ParallelWebpackPlugin = require('parallel - webpack');
module.exports = {
plugins: [
new ParallelWebpackPlugin({
workers: require('os').cpus().length
})
]
};