图片淡入关键在于精准锚定像素就绪时刻,应监听load事件或用intersectionobserver+decode(),配合opacity过渡、内联svg占位、宽高预设及decoding="async"/fetchpriority="high"优化加载节奏。

图片加载完成前先显示模糊占位图
浏览器默认是空白或直接闪现,要“慢慢显示”,本质是控制视觉过渡。最可靠的方式不是靠 CSS 动画延迟,而是用 loading="lazy" + 低质量占位图(LQIP)或 SVG 占位,再配合 opacity 和 transition 实现淡入。
常见错误是只加 opacity: 0; transition: opacity 0.3s; 然后等 JS 改 class —— 但图片还没加载完就触发了,结果白屏一闪再淡入,体验更差。
- 必须监听
img的load事件,或用IntersectionObserver配合decode()确保解码完成后再开动画 - 推荐用内联 SVG 占位:体积小、可缩放、无需额外请求,比如
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"><rect fill="#f0f0f0" width="100%" height="100%"></rect></svg> - 避免对未设置宽高的
img直接设opacity过渡,会导致布局抖动;务必提前声明width/height或用aspect-ratio
用 CSS image-rendering 控制加载中的像素风格(非必需但有用)
某些场景下,你希望加载中那张低质占位图看起来“有意为之”,比如复古风站点。这时可临时启用 image-rendering: pixelated;,让浏览器用最近邻算法放大,避免模糊拉伸。
但它不解决“慢慢显示”,只是优化中间态观感。真正起作用的仍是 opacity + transition + 加载时机控制。
立即学习“前端免费学习笔记(深入)”;
- 仅在占位图阶段生效,真实图片加载后应重置为
image-rendering: auto;或删掉该样式 - 注意兼容性:
pixelated在 Safari 15.4+ 和 Chrome 97+ 支持较好,旧版需用-webkit-optimize-contrast回退(效果不同) - 别对大图全程用
pixelated,会严重损害清晰度
避免用 background-image + opacity 淡入的真实坑
很多人把图片塞进 div 背景里,然后靠 JS 切换 class 淡入。问题在于:background-image 没有原生的加载事件,onload 不触发,naturalWidth 读不到,你根本不知道它啥时候真加载完了。
结果就是:动画提前播完,图还在转圈;或者强行 setTimeout 等个固定时间,网络一慢就露馅。
- 坚持用语义化
img标签,哪怕只是藏在position: absolute里做底层 - 如果非要用背景图,得配合
CSS @property(需注册)+fetch()手动加载 Blob,复杂度陡增,不推荐 - 不要依赖
document.images[n].complete判断——缓存命中时可能为 true,但 DOM 还没渲染,视觉仍为空
现代方案:用 decoding="async" + fetchpriority="high" 加速关键图
“慢慢显示”不等于“慢慢加载”。用户感知的“慢”,常源于加载阻塞,而非动画本身。HTML5 提供了两个轻量级提示属性,能显著改善首屏大图的加载节奏。
它们不改变动画逻辑,但让动画更大概率在用户视线内准时启动。
-
decoding="async"告诉浏览器:这张图的解码可以丢到后台线程,别卡主线程渲染(尤其对 WebP/AVIF 大图有效) -
fetchpriority="high"提升资源调度优先级,比普通img更早发起请求(Chrome 101+,Firefox 119+) - 二者都只对
img标签生效,background-image无法使用 - 慎用
fetchpriority="low":它可能让懒加载图被彻底延后,反而破坏淡入节奏










