Avatar

CaiCai

INITIALIZING SYSTEM

封面

图片闪烁修复总结

2026-07-05 08:40:12
# bug修复
✨ 心情:开心
👁 次阅读

1. 问题现象

首次完全加载后,短时间内再次点击导航进入动漫、照片墙或杂谈页面,封面图片会闪一下灰色背景再显示,或者出现"重新加载"的情况。

2. 根因

2.1 图片过大 → 浏览器解码缓存不稳定

**位置文件原大小解码位图 (RGBA)**照片墙封面6a33ba160508c.jpg3.1 MB~12 MB杂谈封面6a42043d3eef3.png1.2 MB~4 MB

浏览器内存压力大时,解码缓存(decoded bitmap)优先被淘汰。重新挂载时即使 HTTP 缓存命中,仍需重新解码——550KB 图片解码 <1ms,3.1MB 图片解码需 15-50ms。

2.2 页面导航 → 组件卸载重挂载 → 新 元素

Next.js App Router 客户端导航时,页面组件完全卸载,所有 <img> DOM 元素销毁。即使 loadedSet 记录"此 URL 已加载过",新创建的 img 仍需要解码时间。

2.3 无解码缓存保护

原 FadeImage 组件不保留任何 JS 引用,浏览器可以在组件卸载后回收解码位图。

3. 修复方案

3.1 代码层 — components/FadeImage.tsx(共享组件,全局生效)

改动代码作用同步解码decoding={loaded ? "sync" : "async"}已缓存图片同帧绘制,消除解码间隙图片引用保持retainedImages Map + FIFO 30 张持有已解码 img DOM 引用,浏览器无法回收更快过渡duration-500duration-200首次加载淡入 200ms

3.2 样式层 — 背景色调优

文件原始修改后AnimeClient.tsx 封面容器bg-slate-200 dark:bg-slate-700bg-slate-100 dark:bg-slate-800PhotoWallClient.tsx 后层bg-slate-300 dark:bg-slate-700bg-slate-200 dark:bg-slate-800PhotoWallClient.tsx 中层bg-slate-200 dark:bg-slate-600bg-slate-100 dark:bg-slate-700PhotoWallClient.tsx 前层dark:bg-slate-200dark:bg-slate-700

3.3 数据层 — 图片瘦身

位置旧 URL新大小缩减照片墙封面6a33ba160508c.jpg550 KB-82%照片墙 photo[0]6a33b8f1bb035.jpg445 KB—照片墙 photo[1]6a33b9085314e.jpg380 KB—照片墙 photo[2]6a33b9113bb2c.jpg828 KB—杂谈封面6a42043d3eef3.png80 KB-93%

4. 防护机制

第一层loadedSet (模块级 Set)
 记录已加载 URL → 重挂载时跳过 opacity-0 → 直接可见

第二层retainedImages Map
 持有已解码 DOM 引用 → 浏览器无法回收解码位图
 FIFO 上限 30 张,防止内存泄漏

第三层decoding="sync" + duration-200 + 灰色占位
 同步解码 + 快速淡入 + 一致的加载状态兜底

5. 修改文件清单

文件改动类型components/FadeImage.tsx代码 — 核心修复app/anime/AnimeClient.tsx样式 — 背景色app/photowall/PhotoWallClient.tsx样式 — 背景色data/albums.ts数据 — 图片 URL 替换chatters/chatter_1782710072.md数据 — 封面 URL 替换

6. 同步状态

环境路径状态XHBlogs 测试新建文件夹 (2)\XinghuisamaBlogs\XHBlogs\已同步XHBlogs 正式Desktop\XinghuisamaBlogs\XHBlogs\已同步my-blog-manager新建文件夹 (2)\XinghuisamaBlogs\my-blog-manager\已同步