图片骨架屏必须用纯CSS的<div>占位,禁用<img>标签;需用aspect-ratio或padding-top控制宽高比;SSR时须与真实图片DOM同构;动画仅限background-position和transform;加载完成后必须element.remove()。

图片骨架屏不能用 <img> 标签占位
几乎所有初学者都会下意识写 <img src="data:image/svg+xml;base64,..."> 或空 <img src=""> 当骨架,但这是错的。它会触发浏览器解码、占用主线程、干扰资源调度,且无法控制尺寸精度——加载瞬间仍会抖动。真正有效的占位必须是纯 CSS 驱动的 <div>,不带任何语义属性(src、alt、aria-label 一律清空)。
必须用 aspect-ratio 或 padding-top hack 控制宽高比
只设 width: 100% 不设高度,骨架就塌成一条线;用 height: 100% 更糟——父容器没高度时直接归零。现代方案优先写:aspect-ratio: 16 / 9 + width: 100% + overflow: hidden。旧浏览器 fallback 方案是:padding-top: 56.25% + position: relative,再套一层 position: absolute; top: 0; left: 0; width: 100%; height: 100% 的子 <div>。
服务端直出 HTML 时,骨架 <div> 必须和真实图片 DOM 结构同构
如果真实图片是:<img class="card-img" src="/a.jpg" alt="封面">,那骨架就不能是 <div class="skeleton-img"></div>——class 名、标签名、嵌套层级、子节点数都得一致。否则 SSR hydration 时 React/Vue 会丢弃整个节点重挂载,导致闪屏、焦点丢失、表单清空。推荐统一用 <div class="card-img skeleton-img"></div>,靠 CSS 切换显隐,而非删节点或改标签。
动画只允许用 background-position 和 transform
给骨架加 opacity 动画或 left/top 位移,低端设备上极易掉帧,iOS Safari 甚至卡死。正确做法是:background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%) + background-size: 200% 100% + @keyframes { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }。务必加 will-change: transform 提前升层,避免动画启动时临时合成抖动。
立即学习“前端免费学习笔记(深入)”;
最容易被忽略的一点:骨架 DOM 加载完成必须 element.remove(),不是 display: none 或 opacity: 0。残留的骨架节点会持续跑动画、占内存、影响页签性能,尤其在长列表中滚动几十次后明显卡顿。



















