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-500 → duration-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\已同步

