图片/字体等资源优化
图片资源优化
图片通常是前端项目中体积最大的静态资源,优化图片能显著提升页面加载速度。Webpack提供了多种处理图片的loader和插件,帮助我们实现自动化优化。
图片压缩
使用image-webpack-loader
可以在构建阶段自动压缩图片:
module.exports = {
module: {
rules: [
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
optipng: {
enabled: false
},
pngquant: {
quality: [0.65, 0.90],
speed: 4
},
gifsicle: {
interlaced: false
},
webp: {
quality: 75
}
}
}
]
}
]
}
}
Base64编码小图片 对于小于特定尺寸的图片,可以转换为Base64编码内联到代码中:
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192, // 8KB以下的图片转为base64
name: 'images/[name].[hash:8].[ext]'
}
}
]
}
响应式图片处理
使用responsive-loader
生成多尺寸图片:
{
test: /\.(jpe?g|png|webp)$/i,
use: [
{
loader: 'responsive-loader',
options: {
adapter: require('responsive-loader/sharp'),
sizes: [300, 600, 1200, 2000],
placeholder: true,
placeholderSize: 50
}
}
]
}
字体资源优化
字体文件也是影响页面性能的重要因素,特别是中文字体文件通常体积较大。
字体子集化
使用fontmin-webpack
插件提取实际使用的字符:
const FontminPlugin = require('fontmin-webpack');
module.exports = {
plugins: [
new FontminPlugin({
autodetect: true, // 自动提取使用的字符
glyphs: ['额外需要的字符'], // 手动添加字符
allowedFilesRegex: null, // 需要处理的字体文件正则
skippedFilesRegex: null // 跳过的文件正则
})
]
}
WOFF2格式优先 现代浏览器都支持WOFF2格式,它比WOFF有更好的压缩率:
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'fonts/[name].[hash:8].[ext]',
publicPath: '../fonts/'
}
}
]
}
字体加载策略
使用fontfaceobserver
实现无样式文本闪现(FOUT)控制:
// CSS中定义字体
@font-face {
font-family: 'MyFont';
src: url('myfont.woff2') format('woff2');
font-display: swap;
}
// JavaScript中控制加载
const font = new FontFaceObserver('MyFont');
font.load().then(() => {
document.documentElement.classList.add('fonts-loaded');
});
雪碧图生成
将小图标合并为雪碧图可以减少HTTP请求:
const SpritesmithPlugin = require('webpack-spritesmith');
module.exports = {
plugins: [
new SpritesmithPlugin({
src: {
cwd: path.resolve(__dirname, 'src/icons'),
glob: '*.png'
},
target: {
image: path.resolve(__dirname, 'src/assets/sprite.png'),
css: path.resolve(__dirname, 'src/assets/sprite.css')
},
apiOptions: {
cssImageRef: '../assets/sprite.png'
}
})
]
}
SVG优化
SVG作为矢量图形,可以通过多种方式优化:
SVG压缩
使用svgo-loader
自动优化SVG:
{
test: /\.svg$/,
use: [
{
loader: 'svg-url-loader',
options: {
limit: 8192,
encoding: 'base64'
}
},
'svgo-loader'
]
}
SVG Sprite 将多个SVG合并为一个Sprite:
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
use: [
{
loader: 'svg-sprite-loader',
options: {
extract: true,
spriteFilename: 'sprite.svg'
}
}
]
}
]
},
plugins: [
new SpriteLoaderPlugin()
]
}
资源缓存策略
利用Webpack的hash机制实现长期缓存:
module.exports = {
output: {
filename: '[name].[contenthash:8].js',
chunkFilename: '[name].[contenthash:8].chunk.js'
},
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[contenthash:8].[ext]'
}
}
]
}
]
}
}
按需加载非关键资源
使用Webpack的动态导入延迟加载非关键资源:
// 图片懒加载
const lazyImage = document.createElement('img');
import(/* webpackPrefetch: true */ './images/hero.jpg').then(src => {
lazyImage.src = src;
});
// 字体延迟加载
window.addEventListener('load', () => {
import(/* webpackPreload: true */ './fonts/noto-sans-sc.woff2');
});
资源预加载提示
使用preload-webpack-plugin
添加资源预加载提示:
const PreloadWebpackPlugin = require('preload-webpack-plugin');
module.exports = {
plugins: [
new PreloadWebpackPlugin({
rel: 'preload',
include: 'allAssets',
fileWhitelist: [/\.woff2/],
as(entry) {
if (/\.woff2$/.test(entry)) return 'font';
}
})
]
}
现代格式支持
使用新一代图片格式如WebP:
const ImageminWebpWebpackPlugin = require('imagemin-webp-webpack-plugin');
module.exports = {
plugins: [
new ImageminWebpWebpackPlugin({
config: [{
test: /\.(jpe?g|png)/,
options: {
quality: 75
}
}],
overrideExtension: true,
detailedLogs: true
})
]
}
资源内联决策
合理选择需要内联的资源:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const InlineSourceWebpackPlugin = require('inline-source-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin(),
new InlineSourceWebpackPlugin({
compress: true,
rootpath: './src',
test: [/\.(js|css)$/, /critical\.(css|js)$/]
})
]
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:合理配置resolve选项
下一篇:代码压缩策略与工具选择