给 AI 写骨架屏加上尺寸验收约束
AI 生成的通用骨架屏容易忽略真实组件的高度、间距与响应式布局,导致内容加载后页面跳动。文章建议提供真实组件或 Storybook 示例,并明确高度误差、布局结构和样式复用要求。
AI 深度解读
AI 写的骨架屏经常很好看,却撑不住真实内容的高度:灰色占位卡片只有半张商品卡那么高,数据一回来,下面的内容就被挤走。原文作者的要求很直接:把高度匹配设为验收条件,不能只检查「有没有加载态」。
这篇短文值得读的地方,是把一句模糊的「加个骨架屏」,改成可测量、可对照的任务。不过,作者给的是实践方法,没有提供 CLS 改善的实测数据。
骨架屏为什么有了,页面还是会跳
骨架屏(Skeleton)用占位形状提示内容正在加载,同时提前占住内容需要的空间。如果它只做到了前一件事,用户仍然会看到布局跳动。
作者观察到,AI 容易套用「三行文字加头像」的通用模板,却忽略真实卡片里的图片区域、内边距,以及占了多行的元信息。单独看很整齐的 h-4 横条,放进页面后可能完全对不上内容结构。
响应式布局也容易漏掉。原文提到移动端可能更紧凑、桌面端卡片更高,骨架屏却只适配了其中一个断点。PR 看起来已经补齐加载态,实际切换时依然会挤动周围内容。
骨架屏的验收重点,是加载前后能否保住空间。
把「看着差不多」改成 ±8px 的约束
作者的做法,是先给 AI 真实组件代码,或者对应的 Storybook story,再要求它按几何结构实现占位。
下面这段提示词把目标、复用要求和评审方式放到了一起:
Add a loading skeleton for `ProductCard`.
Constraints:
- Match the loaded card’s outer height ±8px at the default Storybook viewport
- Preserve the same grid/flex structure (media block + title row + price row)
- Use the same padding tokens / gap as the loaded card
- No new skeleton library — reuse our existing `Skeleton` primitive
- Show both states side-by-side in Storybook (`Loading` + `Loaded`) so the jump is obvious in review
If you can’t match height without inventing fake content, stop and explain why.
最关键的是 ±8px 那一行。它让「接近真实高度」变成了可检查的条件,并限定在默认 Storybook 视口下,避免 AI 用一句「已经差不多」交差。
其余约束也有明确用途:沿用相同的 grid/flex 结构,让媒体块、标题行、价格行各自占位;复用 padding token 和 gap,减少两套样式之间的偏差;继续使用已有的 Skeleton 基础组件,避免顺手引入新的 shimmer 动效库或零散灰色色值。
最后一句则要求 AI 在无法匹配时解释原因。真实内容的信息不足,就应该暴露这个缺口,而不是靠编造占位内容凑出一个高度。
我的判断
我赞同把结构匹配放进验收条件。它比单纯调整灰条宽度更接近问题所在,也方便评审者围绕可见差异讨论。
但 ±8px 是作者采用的阈值,原文没有给出选择依据,也没有提供与其他容差的对照数据,不能把它当成通用标准。作者提到布局跳动会推高 CLS(累计布局偏移),却没有报告修复前后的测量结果,因此效果幅度仍属于未验证部分。
另一个前提是「真实内容高度」能够确定。标题换行、元信息数量变化时,该以哪一种内容作为基准?原文没说清。默认 Storybook 视口对齐,也只能证明这一组条件成立,不能自动覆盖所有断点和内容长度。
与普通 spinner 相比,骨架屏能表达内容结构;但如果组件本来就有稳定的外部尺寸,保留容器空间再显示加载指示,也值得考虑。不能只因骨架屏更像成品,就认定它一定更合适。
能拿来做什么
- 给 AI 补加载态时,附上真实组件或 Storybook story,并写明高度容差、结构和间距要求,不要只发一句「加个骨架屏」。
- 在 Storybook 中同时展示
Loading和Loaded,再切换两种状态观察周围内容是否移动,把这一步纳入组件评审。 - 检查移动端和桌面端的占位结构,尤其关注媒体区域和多行信息;内容高度不固定时,先明确用哪些内容样本验收。
- 要求 AI 复用项目已有的
Skeleton和设计 token;发现它新增依赖或独立间距值时,先核对是否确有必要。