骨架屏是模拟真实dom结构的视觉占位,不能仅用纯css灰色div实现,否则会导致布局抖动、fouc和重排;必须结构一致、尺寸对齐、层级匹配,并原子化切换以保障无缝过渡。

什么是骨架屏,为什么不能用纯 CSS 模拟 loading?
骨架屏不是“加个灰色 div 就完事”,它是对真实 DOM 结构的视觉占位。纯 CSS 画几个 div 模拟 loading,等真实内容渲染后靠 display: none 切换,会导致布局抖动、FOUC(Flash of Unstyled Content),甚至触发浏览器重排——尤其在弱网或低端设备上,用户会看到“先闪灰块、再闪内容”的割裂体验。
关键判断:骨架屏必须和真实组件结构一致、尺寸对齐、层级匹配,且切换需原子化(不重绘布局)。
React/Vue 中用 React.memo 或 v-if 控制骨架屏渲染时机
常见错误是把骨架屏写死在模板里,或者用 loading 状态简单控制显隐。这容易导致骨架屏残留(比如请求已返回但状态未及时更新),或提前消失(数据还没 ready 就切走了)。
实操建议:
- 骨架屏组件应与业务组件同级封装,共享同一份 loading 判断逻辑(如
!data || data.length === 0) - React 中用
React.memo包裹骨架组件,避免重复渲染;Vue 中用v-if="!data"而非v-show,确保 DOM 卸载干净 - 服务端渲染(SSR)场景下,骨架屏必须和服务端返回的首屏 HTML 结构完全一致,否则 hydration 会失败,出现“内容闪跳”
用 content-visibility: auto 提升长列表骨架屏性能
列表页骨架屏如果一次性渲染上百个灰色卡片,即使不可见也会触发 layout 和 paint,拖慢首屏时间。Chrome 105+ 支持的 content-visibility: auto 可以让浏览器跳过不可见区域的渲染计算。
使用注意点:
- 仅适用于有明确高度的容器(需设置
height或contain-intrinsic-size) - 配合
will-change: content-visibility可加速切换时的重绘 - 不要在
position: fixed或transform元素上使用,会失效 - 兼容性兜底:老浏览器中降级为
visibility: hidden+height: 0
骨架屏 SVG 占位图慎用 viewBox 缩放
很多团队用 SVG 画骨架图,图省事直接设 viewBox="0 0 375 667" 并用 width="100%" 自适应。问题在于:SVG 内部文字、圆角、阴影等会随缩放失真,尤其在高 DPR 设备上边缘模糊,且无法响应字体大小变化(比如用户设置了系统大号字体)。
更稳妥的做法:
- 用
px单位固定 SVG 内部元素尺寸(如<rect width="200px" height="16px"></rect>) - 外部容器用
max-width+aspect-ratio控制比例,而非依赖 viewBox 缩放 - 关键文本占位改用伪元素
::before+background-color,保证清晰度和可访问性
复杂点在于:骨架屏不是“做出来就行”,它得在加载完成瞬间无缝接管真实 DOM 的几何信息。任何尺寸错位、z-index 冲突、transition 延迟,都会暴露底层实现的粗糙。最常被忽略的是:没给骨架元素加 aria-hidden="true",导致读屏器把灰色块当真实内容朗读。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











