R3.05.4render-blocking first paint设计

阻塞渲染的资源决定首次可见的时刻

别名: 渲染阻塞 · render-blocking CSS · 首绘等待 · CSSOM 阻塞

概念解释

浏览器在关键 CSS、同步脚本、以及仍处于阻塞期的字体就绪之前,可以不绘制第一帧。这些资源叫渲染阻塞资源(render-blocking resources)。它们决定的是首次可见的时刻:屏幕何时从空白变成有内容,而不是控件何时能点、主线程何时空闲。看得见和能操作是两件事;这里只管前一件——第一帧被谁拦住。

机制

HTML 解析遇到外部样式表时会构建 CSSOM;没有 CSSOM,引擎不愿画出无样式内容闪烁,于是首绘等待样式。文档中的同步脚本打断解析,脚本跑完之前后续 HTML 进不了 DOM,首绘同样推迟。字体若走阻塞策略,文本节点可以占着布局却不画字形,首屏看起来像缺了字。链路是:阻塞资源 → 推迟第一帧 → 用户仍对着空白或残缺首屏。

这与“内容后到推动已绘节点”不是同一条时间线。阻塞发生在第一帧之前,用户还没有已呈现元素可被推动;偏移发生在第一帧之后。把首绘推迟,有时反而减少偏移,因为更多盒子在第一次绘制时已经齐套——代价是空白更久。优化首绘是缩短阻塞链,不是把阻塞改成绘制后插入。

边界

media 不匹配的样式表、异步/延迟脚本、非阻塞的字体策略,默认不挡住第一帧。HTTP/2 多路复用能缩短传输,但不改变“CSSOM 未完成就不首绘”的规则。服务端渲染出的 HTML 若仍链接一份巨大的阻塞 CSS,首绘照样等这份 CSS。原生应用的视图树没有这套 CSSOM 阻塞模型;它们的首帧受启动和主线程初始化约束,机制不同。离线已缓存的阻塞资源可以把首绘推得很早,现场冷启动则不能用这个时间。

怎么落地

  • 把首屏真正用到的 CSS 内联或拆成首屏专用文件,其余样式异步加载;同步脚本移出首屏关键路径。
  • 字体用预加载缩短阻塞窗口,但不要用“整包字体下载完再绘”换取所谓的整齐首屏。
  • 在瀑布图里标出第一帧之前仍未结束的 CSS、同步 JS 和阻塞字体,逐项改成非阻塞或拆小。
  • 验证:节流网络下量第一次有内容的绘制时间;去掉或推迟可疑资源后,首绘应前移,且不要把原阻塞工作改成首绘之后往已绘流里插块。

延伸

  • 同组R3.05.1 内容后到会推动已呈现元素 · R3.05.2 位移会造成误点击 · R3.05.3 需为动态内容预留空间 · R3.05.5 已交互的区域不应被后到内容重排 · R3.05.6 异步插入的内容优先占据不打断阅读的位置
  • 相邻R3.15 首屏指标与交互就绪 · R3.06 字体加载 · I2.07 感知性能
  • 站内检索render-blocking · first paint · CSSOM

同组卡片

快捷操作

分享

分享当前页面

ios_share

https://hci.top/zh/handbook/R3.05.4