首屏白屏时间长而 domcontentloaded 早触发,是因为浏览器渲染需完成 cssom 构建才能生成 render tree,外部 css 阻塞渲染;必须内联首屏关键 css(如 .hero-title、.cta-button),用 critters 等工具自动化提取并控制体积≤14kb,非关键 css 通过 media="print" onload 或动态插入异步加载。

为什么首屏白屏时间长,但 DOMContentLoaded 很早就触发了
因为浏览器渲染不只等 DOM 构建完成——它还得等关键 CSS 加载、解析、构建 CSSOM,再结合 DOM 生成 Render Tree。如果 <link rel="stylesheet"> 指向的是未优化的外部 CSS 文件,哪怕 HTML 已解析完,页面照样白屏。
典型现象:Network 面板里 main.css 的 Initiator 显示为 parser,且耗时 >200ms;Performance 面板中 Recalculate Style 被卡在 CSS 加载之后。
- 绝对别用
@import引入关键样式——它强制串行加载,实测拖慢 FCP 300ms+ - 不要把整站 CSS 打包进一个
app.css然后全量加载——非首屏模块(如后台管理页、弹窗组件)的样式会白白阻塞首屏 - 内联不是“把所有 CSS 塞进
<style></style>”,而是只提取真正用于首屏渲染的规则(比如.hero-title、.cta-button、导航栏固定高度等)
怎么提取并内联首屏关键 CSS
手动提取容易漏、难维护,推荐用工具链自动化。核心逻辑是:基于真实首屏 HTML 快照,跑一遍 CSS 覆盖率分析,只保留被用到的选择器。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 本地开发可用
puppeteer+critters:启动无头浏览器访问http://localhost:3000,抓取首屏 DOM,计算覆盖的 CSS 规则,输出内联<style></style>片段 - Vite 用户直接配
vite-plugin-critical,build 时自动生成 critical CSS 并注入index.html - Webpack 项目用
mini-css-extract-plugin分离出critical.css,再用html-webpack-plugin的templateParameters注入内联内容 - 注意:内联 CSS 体积建议控制在
14KB内(HTTP/2 下单个 TCP 包的理想大小),超了反而增加解析开销
非首屏 CSS 怎么延迟加载又不破坏媒体查询
不能简单删掉 <link rel="stylesheet">,否则响应式断点、暗色模式等逻辑会失效。关键是让浏览器先跳过加载,等首屏稳定后再触发。
- 用
media="print"初始化:<link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'">—— 浏览器默认不加载 print 样式,onload在资源就绪后才切换 media,避免 FOUC - 更稳妥的做法是配合
requestIdleCallback或DOMContentLoaded后动态插入:link.rel = 'stylesheet',确保 DOM 就绪后再加载 - 对条件加载场景(如仅桌面端需要的布局),直接用
media="(min-width: 768px)",浏览器原生支持,无需 JS 干预 - 禁用
prefetch加载这类 CSS——它的优先级太低,可能等用户划到第二屏了还没下完
preload 关键 CSS 时最容易踩的三个坑
<link rel="preload"> 不是加了就快,写错反而抢带宽、拖慢整体。
- 必须带
as="style":缺了这个,浏览器当普通脚本处理,无法参与 CSSOM 构建,等于白写 - 必须加
crossorigin属性(哪怕资源同源):字体、CSS 若含跨域请求(比如 CDN 上的 CSS),没这个属性会导致 preload 失效或 CORS 错误 - 别 preload 整个
app.css:它包含大量非首屏规则,浪费带宽;应该只 preload 提取后的critical.css,且该文件需独立存在、路径明确 - 验证方式:Chrome DevTools → Network → 找到预加载资源 → 查看 Priority 列是否为
high;若显示low或为空,说明as或crossorigin没配对
关键 CSS 优化不是一次配置就能一劳永逸的事——页面结构变、首屏内容变、用户设备分布变,都会影响“什么是关键”。上线后得持续用 Lighthouse 跑 FCP 和 LCP,盯着实际指标调,而不是只看代码有没有 <style></style> 标签。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










