vite-plugin-img-preload
v1.9.1
Published
Vite plugin for image preloading
Maintainers
Readme
vite-plugin-img-preload
[
](https://www.npmjs.com/package/vite-plugin-img-preload)
一个用于自动生成图片预加载标签的 Vite 插件,帮助提升网站首屏加载性能和用户体验。
功能特点
- ✨ 自动扫描指定目录下的图片文件
- 🚀 在 HTML 中添加
<link rel="preload">标签实现图片预加载 - 🔍 支持按需过滤,只预加载特定图片
- 🔄 支持处理带哈希文件名的图片资源
- 🛠️ 可控制在开发环境中是否启用
- 🌐 开发和生产环境均可配置
安装
# npm
npm install vite-plugin-img-preload --save-dev
# yarn
yarn add vite-plugin-img-preload -D
# pnpm
pnpm add vite-plugin-img-preload -D基本使用
在 vite.config.js 或 vite.config.ts 中配置插件:
import { defineConfig } from 'vite';
import imgPreload from 'vite-plugin-img-preload';
export default defineConfig({
plugins: [
imgPreload()
]
});这将自动扫描 public/images 目录下的所有图片,并在 HTML 的 <head> 中添加预加载标签。
默认行为:
- 🔧 只在生产环境(
npm run build)中启用 - 📁 扫描
public/images目录 - 🖼️ 支持 png, jpg, jpeg, gif, webp, avif, svg 格式
配置选项
完整配置示例
import { defineConfig } from 'vite';
import imgPreload from 'vite-plugin-img-preload';
export default defineConfig({
plugins: [
imgPreload({
// 图片目录路径,相对于项目根目录
dir: 'public/assets/images',
// 资源路径前缀,通常与 dir 的最后一部分对应 //
prefix: '/assets/images/',
// 是否处理带哈希的文件名。如果图片被 Vite 打包并添加哈希,必须设置为 `true`
hash: true,
// 是否在开发环境中启用预加载
enableInDev: false,
// 按需过滤函数
filter: (filename, filepath) => {
// 只预加载首屏关键图片
return filename.includes('hero') ||
filename.includes('logo') ||
filename.startsWith('banner-');
},
// 转换函数:关键图片用 preload,其他用 prefetch
transform: (filename, filepath) => {
// 关键图片使用 preload(优先级更高)
if (filename.includes('hero') || filename.includes('logo')) {
return 'preload';
}
// 其他图片使用 prefetch(较低优先级)
return 'prefetch';
},
// 全局 rel 属性(当未使用 transform 时生效)
rel: 'preload' // 可选:'preload' | 'prefetch'
})
]
});选项详解
| 选项 | 类型 | 默认值 | 描述
|-----|-----|-----|-----
| dir | string | 'public/images' | 图片目录路径,相对于项目根目录
| prefix | string | 自动从 dir 推断 | 资源路径前缀,用于生成图片的 URL
| hash | boolean | false | 是否处理带哈希的文件名。如果图片被 Vite 打包并添加哈希,必须设置为 true
| enableInDev | boolean | false | 是否在开发环境中启用预加载功能
| filter | Function | undefined | 按需过滤函数,返回 true 表示预加载该图片
| transform | Function | undefined | 转换函数,返回 'preload' 或 'prefetch'
| rel | string | 'preload' | 全局 rel 属性,当未使用 transform 时生效
filter 函数
filter 函数接收两个参数:
filter: (filename: string, filepath: string) => booleanfilename: 图片文件名(如logo.png)filepath: 图片文件的完整路径(如/path/to/project/public/images/logo.png)
返回 true 表示该图片将被预加载,返回 false 则跳过。
transform 函数
transform 函数用于决定每个图片使用 preload 还是 prefetch:
transform: (filename: string, filepath: string) => 'preload' | 'prefetch'filename: 图片文件名(如logo.png)filepath: 图片文件的完整路径(如/path/to/project/public/images/logo.png)
返回值:
'preload': 高优先级预加载,适用于关键图片(如首屏图片、Logo)'prefetch': 低优先级预加载,适用于可能需要的图片(如次要内容图片)
区别说明:
- preload: 浏览器会立即开始下载,优先级高
- prefetch: 浏览器在空闲时下载,优先级低,不会阻塞关键资源
rel 选项
rel 选项用于全局设置所有图片的 rel 属性:
imgPreload({
rel: 'prefetch' // 所有图片都使用 prefetch
})优先级:transform 函数 > rel 选项 > 默认值 ('preload')
- 如果设置了
transform函数,会优先使用函数的返回值 - 如果没有
transform函数,使用rel选项的值 - 如果都没有设置,默认使用
'preload'
enableInDev 选项
enableInDev 控制插件在开发环境中是否启用:
false(默认):插件仅在生产环境(build)中启用,开发环境(dev/serve)中不生效true:插件在开发环境和生产环境中都启用
在开发环境中启用预加载可能会影响热更新性能,但对于测试预加载功能很有用。
使用场景
1. 预加载首屏关键图片
imgPreload({
filter: (filename) => {
// 只预加载首屏关键图片
const criticalImages = ['hero.jpg', 'logo.svg', 'banner.png'];
return criticalImages.includes(filename);
}
})2. 按图片类型过滤
imgPreload({
filter: (filename) => {
// 只预加载 WebP 和 AVIF 格式的图片
return /\.(webp|avif)$/i.test(filename);
}
})3. 多目录配置
如果需要预加载多个目录下的图片,可以注册多个插件实例:
plugins: [
imgPreload({ dir: 'public/images' }),
imgPreload({ dir: 'public/icons', prefix: '/icons/' })
]4. 处理带哈希的图片文件
当图片文件被 Vite 打包并添加哈希时:
imgPreload({
dir: 'src/assets/images', // 被 Vite 处理的图片目录
prefix: '/assets/',
hash: true // 必须设置为 true 以正确解析哈希文件名
})5. 智能 preload/prefetch 策略
使用 transform 函数实现智能加载策略:
imgPreload({
dir: 'public/images',
transform: (filename, filepath) => {
// 关键图片使用 preload(立即加载)
const criticalImages = ['hero', 'logo', 'banner'];
if (criticalImages.some(keyword => filename.includes(keyword))) {
return 'preload';
}
// 其他图片使用 prefetch(空闲时加载)
return 'prefetch';
}
})6. 全局设置 rel 属性
使用 rel 选项全局设置所有图片的加载策略:
// 所有图片都使用 prefetch
imgPreload({
dir: 'public/images',
rel: 'prefetch'
})
// 结合 filter 使用,只对特定图片使用 prefetch
imgPreload({
dir: 'public/images',
rel: 'prefetch',
filter: (filename) => filename.includes('gallery')
})7. 在开发环境中启用预加载
imgPreload({
dir: 'public/images',
enableInDev: true // 在开发环境中也启用预加载
})工作原理
- 插件在构建过程中扫描指定目录下的图片文件
- 根据配置和过滤条件选择需要预加载的图片
- 在 HTML 的
<head>中插入<link rel="preload" as="image">标签 - 浏览器加载 HTML 时会提前请求这些图片资源
生成的 HTML 代码示例:
<head>
<!-- 其他 head 标签 -->
<!-- Preload images (vite-plugin-img-preload) -->
<link rel="preload" href="/images/logo.png" as="image" />
<link rel="preload" href="/images/hero.jpg" as="image" />
<link rel="preload" href="/images/banner.webp" as="image" />
</head>带哈希的输出示例:
带哈希的输出示例:
<!-- 当 hash: true 时 -->
<link rel="preload" href="/assets/hero-a1b2c3d4.jpg" as="image" />
<link rel="preload" href="/assets/logo-e5f6g7h8.png" as="image" />使用 transform 的输出示例:
<!-- 关键图片使用 preload -->
<link rel="preload" href="/images/hero.jpg" as="image" />
<link rel="preload" href="/images/logo.png" as="image" />
<!-- 其他图片使用 prefetch -->
<link rel="prefetch" href="/images/gallery-1.jpg" as="image" />
<link rel="prefetch" href="/images/gallery-2.jpg" as="image" />性能影响
✅ 优势
- 提升首屏加载速度:关键图片提前加载,减少用户等待时间
- 改善用户体验:避免图片加载时的布局抖动
- 优化 LCP 指标:对于图片作为最大内容绘制元素的页面特别有效
⚠️ 注意事项
- 带宽消耗:预加载会增加初始页面的网络请求
- 缓存策略:确保预加载的图片能被浏览器缓存
- 移动端考虑:在移动网络环境下谨慎使用大量预加载
最佳实践
- 只预加载关键图片:过多的预加载会占用带宽,影响其他资源加载
- 优先考虑首屏图片:优先预加载首屏可见的关键图片
- 考虑图片大小:避免预加载过大的图片,建议限制在 200KB 以内
- 结合图片格式优化:使用现代图片格式如 WebP、AVIF 可以减小文件大小
- 开发环境谨慎启用:开发环境中通常不需要预加载,除非需要测试预加载功能
- 配合懒加载使用:对于非首屏图片,结合懒加载技术使用
常见问题
图片未被预加载
排查步骤:
- 检查目录路径:确认
dir选项指向的目录存在且包含图片文件 - 检查文件格式:确认图片文件扩展名受支持(支持:png, jpg, jpeg, gif, webp, avif, svg)
- 检查过滤条件:如果使用了
filter函数,确认过滤逻辑返回true - 检查环境设置:开发环境测试需设置
enableInDev: true - 检查构建输出:查看生成的 HTML 文件中是否包含 preload 标签
调试技巧:
// 添加调试信息
imgPreload({
filter: (filename, filepath) => {
console.log('Processing:', filename); // 调试输出
return filename.includes('hero');
}
})带哈希文件名的图片路径不正确
如果您的图片文件被 Vite 打包处理并添加了哈希(如 image.abc123.jpg),请确保设置 hash: true 选项:
imgPreload({
dir: 'src/assets/images', // 被 Vite 处理的图片目录
hash: true // 必须设置为 true
})重要说明:
public目录下的图片:通常不会被 Vite 哈希处理,应设置hash: false(默认值)src目录下通过import引入的图片:会被 Vite 哈希处理,必须设置hash: true- 插件会自动从构建产物(bundle)中解析正确的哈希文件路径
开发环境中预加载不生效
默认情况下,插件在开发环境中不启用。如需在开发环境中测试预加载功能,请设置 enableInDev: true。
与其他插件的兼容性
本插件与大多数 Vite 插件兼容,包括但不限于:
@vitejs/plugin-vue@vitejs/plugin-reactvite-plugin-pwavite-plugin-html
浏览器兼容性
<link rel="preload"> 在现代浏览器中得到广泛支持:
- Chrome 50+
- Firefox 56+
- Safari 11.1+
- Edge 17+
贡献指南
欢迎提交 Issues 和 Pull Requests!
- Fork 本仓库
- 创建您的特性分支 (
git checkout -b feature/amazing-feature) - 提交您的更改 (
git commit -m 'Add some amazing feature') - 推送到分支 (
git push origin feature/amazing-feature) - 打开一个 Pull Request
更新日志
v1.9.0
- ✨ 新增
transform选项,支持智能选择preload或prefetch - ✨ 新增
rel选项,支持全局设置rel属性 - 🎯 支持关键图片使用
preload,其他图片使用prefetch的智能加载策略 - 📚 完善的 TypeScript 类型定义和文档
v1.8.0
- ✨ 新增
enableInDev选项,支持在开发环境中启用预加载 - 🐛 修复哈希文件名匹配逻辑
- 📚 完善文档说明
v1.6.x
- 🔄 支持处理带哈希的文件名
- 🎯 改进文件匹配算法
许可证
MIT © BugfreeYeti
相关资源
如果您觉得这个插件有用,请给它一个 ⭐️!
