诡异!vite+vue3 项目图片无法显示,我怀疑人生…

问题背景

在一个基于 vite + vue3 的项目中,我遇到了一个让我差点怀疑人生的诡异问题:

  • 项目本地开发环境下,所有图片资源(无论是通过 v-if 控制的 <img> 标签,还是 CSS background-image,亦或是通过 new URL() 动态导入的图片)都无法正常显示、严重延迟

  • 元素上有动画,直接导致元素看不见背景图 ,但检查 Style 面板,background 样式明明正常。

  • 图片路径反复确认,完全正确,不存在拼写错误。

  • 打开浏览器 Network 面板:图片请求已发出,状态码 304(从缓存读取),Elements 面板 DOM 也正常,但页面就是一片空白。

  • 大量图片请求长期处于 pending,尤其是 CSS 背景图,加载时间甚至达到 6.92s ,严重阻塞渲染。

排查过程

第一步:怀疑网络环境(VPN)问题

首先怀疑是本地 VPN 代理干扰本地服务:

  • 调整 VPN,把 localhost127.0.0.1192.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 机制 = 图片被 "挤死" 在队列里

  1. HTTP/1.1 限制

    浏览器对同一个域名 ,默认只允许 6 个并行 TCP 连接,多出来的请求必须排队。

  2. Vite ESM 的 "副作用"

    Vite 开发环境不打包,使用原生 ESM 加载。

    一刷新页面,浏览器瞬间收到 几十上百个 .js/.vue 模块请求

  3. 资源优先级抢占

    浏览器 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 实战避坑技巧,一起少走弯路!

相关推荐
掘金安东尼1 小时前
活动落地页效率翻倍:RollCode 这次更新有点猛
前端·低代码·面试
FE_winter2 小时前
OpenClaw Skills 进阶实战:前端开发者的 AI 技能库搭建指南
前端·后端·程序员
wordbaby2 小时前
小白也能看懂:小程序 Canvas 给图片添加水印的终极指南
前端·canvas
Mapmost2 小时前
“汛”速响应:流域洪水仿真分析,如何实现淹没过程的精准推演?
前端
梁大虎2 小时前
Electrobun 开发必看:CEF 依赖下载失败?手动解压一招搞定!
前端·javascript·后端
青青家的小灰灰2 小时前
拒绝 Prop Drilling 与隐式耦合:Vue 组件通讯的全景指南与最佳实践
前端·javascript·vue.js
代码老中医2 小时前
我赌5年后,90%的CRUD页面都是AI生成的
前端
bluceli2 小时前
前端监控与错误追踪实战指南:构建稳定应用的终极方案
前端·监控
streaker3032 小时前
多 IDE/Agent 环境下的 Skill 管理方案
前端·javascript·ai编程