骨架屏自动生成不能靠运行时js插入,因fcp只认初始html中的可绘制内容,需构建时注入;ast解析工具要求代码静态可分析,禁用动态class、动态导入和函数props;服务端直出需匹配ssr/hydration,vue用data-skeleton属性,react用insertadjacenthtml;深色模式应使用css变量,避免深层嵌套和触发布局的动画属性。

骨架屏自动生成为什么不能靠运行时 JS 插入
因为浏览器解析 HTML 时根本看不到它——document.createElement 或 v-if="loading" 生成的骨架节点,都在 DOMContentLoaded 之后才出现,FCP(First Contentful Paint)完全不认。Lighthouse 报告里 FCP >2s 却“明明有骨架”,问题就在这儿。
- FCP 只认文本、图片、
<canvas></canvas>、SVG 中的<image></image>这类可绘制内容,纯div+background: linear-gradient不算 - 构建时注入才能让骨架节点随初始 HTML 一起到达浏览器,被 HTML 解析器直接消费
- Vue 的
v-skeleton和 React 的react-skeleton-generator都依赖 AST 静态分析,不是在浏览器里跑一遍组件再截图
AST 解析型工具对代码结构的硬性要求
这类工具不执行 JS,只读 JSX/Template 语法树,任何动态性都会导致漏节点或崩溃。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
-
className不能拼接:class={`skeleton ${isCard ? 'card' : 'list'}`}→ 解析失败 - 子组件不能用
import()动态加载:必须提前写死,否则构建时 AST 里根本没这个节点 - props 不能传函数或复杂对象:
<list items="{data}" renderitem="{renderItem}"></list>→renderItem无法推断,整个List可能被跳过 - 推荐显式包裹:
<skeleton-wrapper>{children}</skeleton-wrapper>,而不是透传{children}
服务端直出骨架 HTML 的关键配置点
骨架要真正提升感知性能,必须和 SSR/hydration 流程对齐,否则 hydration mismatch 会触发整页重渲染。
- Vue 场景下,骨架节点必须带
data-skeleton属性,且不能被v-if包裹——v-show或 class 切换更安全 - React 场景下,生成的 HTML 片段需通过
document.getElementById('root').insertAdjacentHTML('afterbegin', skeletonHtml)注入,不能用innerHTML,避免销毁已有 DOM 节点 - 骨架节点里禁用
@import和嵌套@media:老浏览器不支持内联<style></style>里的这些规则,会导致样式失效 - 图片占位建议用 base64 空图或固定宽高色块,避免
<img src="">触发 404 请求或 layout shift
深色模式与动画性能的隐蔽陷阱
用 background: linear-gradient 做骨架动画很常见,但直接写死颜色值会让深色模式下灰块刺眼;多层嵌套 div 模拟卡片还会拉长 HTML 解析耗时。
- 深色模式适配:改用
color-scheme: light dark+CSS custom property,比如--skeleton-bg: #eee和--skeleton-bg-dark: #333 - 避免 DOM depth > 5:一个卡片用 1 个
<div class="skeleton-card"> + 内联伪元素模拟图文,比 7 层嵌套 <code>div更快解析 - 动画别用
transform或opacity以外的属性:width/height触发 layout,background-position在低端设备上掉帧严重 - 骨架显示时长必须可控:JS 加载完立刻隐藏,别等所有图片 onload,否则用户看到“骨架闪一下→空白→真实内容”,体验比不用还差 真正落地的骨架屏,从来不是加个 loading 动画那么简单。它卡在构建流程、AST 可分析性、服务端输出时机、CSS 渲染路径四条线上,任意一环松动,就会变成拖慢 FCP 的累赘。










