问题背景
在一个基于 vite + vue3 的项目中,我遇到了一个让我差点怀疑人生的诡异问题:
-
项目本地开发环境下,所有图片资源(无论是通过
v-if控制的<img>标签,还是 CSSbackground-image,亦或是通过new URL()动态导入的图片)都无法正常显示、严重延迟。 -
元素上有动画,直接导致元素看不见背景图 ,但检查 Style 面板,
background样式明明正常。 -
图片路径反复确认,完全正确,不存在拼写错误。
-
打开浏览器 Network 面板:图片请求已发出,状态码 304(从缓存读取),Elements 面板 DOM 也正常,但页面就是一片空白。
-
大量图片请求长期处于
pending,尤其是 CSS 背景图,加载时间甚至达到 6.92s ,严重阻塞渲染。
排查过程
第一步:怀疑网络环境(VPN)问题
首先怀疑是本地 VPN 代理干扰本地服务:
- 调整 VPN,把
localhost、127.0.0.1、192.168.*加入「绕过代理」 - 关闭 VPN 重启项目
- 结果:图片依然无法显示,排除 VPN 问题。
第二步:深入 Network Timing 分析
排除路径与代理后,我点开了一个长时间 pending 的图片,查看 Timing:

scss
Queueing(排队):5.29 ms
Stalled(停滞):4.84 s
Request sent:0 µs
Waiting (TTFB):0.24 ms
Content Download:0.37 ms
- Queueing:浏览器把请求加入队列,等待连接
- Stalled :请求已准备好,但被浏览器强行暂停近 5 秒!
- 服务器响应、下载都极快,问题完全出在等待阶段。
这就是典型的:对头阻塞(Head-of-line Blocking)。
第三步:结合 Vite 原理定位根本原因
真相只有一个:
HTTP/1.1 并发限制 + Vite ESM 机制 = 图片被 "挤死" 在队列里
-
HTTP/1.1 限制
浏览器对同一个域名 ,默认只允许 6 个并行 TCP 连接,多出来的请求必须排队。
-
Vite ESM 的 "副作用"
Vite 开发环境不打包,使用原生 ESM 加载。
一刷新页面,浏览器瞬间收到 几十上百个 .js/.vue 模块请求。
-
资源优先级抢占
浏览器 JS/CSS 优先级 > 图片。
6 个连接瞬间被 JS 占满,图片只能无限期 Stalled,直到连接释放。
这就是:Vite 越快,图片越容易阻塞。
解决方案(4 种方案,从简单到进阶)
方案一:开启 HTTP/2
HTTP/2 支持多路复用,一条连接同时跑百个请求,彻底解决对头阻塞。
Vite 开启只需一行配置:
typescript
运行
javascript
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
// 开启 HTTPS,自动启用 HTTP/2
https: true,
port: 5173
}
})
说明:HTTP/2 必须基于 HTTPS,Vite 会自动生成自签名证书。
首次访问浏览器提示不安全 → 高级 → 继续访问即可。
效果:
- 协议变为
h2 - Stalled 时间直接归 0
- 所有图片秒加载
方案二:资源内联(小图片首选)
把小图片转为 base64,不发 HTTP 请求。本地开发环境就不转了。
yaml
// vite.config.ts
build: {
assetsInlineLimit: 4096 // 4KB 以下自动内联
}
优点:
- 彻底消灭请求
- 背景图、img 都适用
方案三:资源优先级控制
告诉浏览器:哪些图片必须先加载。
xml
<!-- 高优先级 -->
<img src="..." fetchpriority="high" />
<!-- 懒加载、低优先级 -->
<img src="..." loading="lazy" fetchpriority="low" />
CSS 背景图也可以延迟挂载:
scss
onMounted(() => {
setTimeout(() => {
dom.classList.add('bg-loaded')
}, 500)
})
方案四:预连接 & 预获取
提前建立连接、提前加载关键图。
xml
<!-- 预连接 -->
<link rel="preconnect" href="http://localhost:5173">
<!-- 预加载关键图 -->
<link rel="preload" href="/bg.png" as="image">
大幅降低首屏图片等待时间。
结果验证
我采用了升级http 的方式解决,比较高效,快速一些。
开启 HTTP/2 后:
- Network 协议变为
h2 - Stalled 时间从 4.84s → 几 ms
- 所有图片(v-if、背景图、动态图)瞬间显示
- 动画正常展示,不再出现 "有元素无图" 的诡异现象
最后
✨ 有没有前端小伙伴跟我一样,遇到过这种 "路径没错、DOM 没错,就是不显示" 的诡异 bug?评论区说说你踩过的 vite 坑~
如果这篇排查过程帮你避开了坑,麻烦点赞 + 收藏呀,关注我,后续分享更多 vite + vue3 实战避坑技巧,一起少走弯路!