,让首屏在 1.8 秒内渲染)
Front-End-Checklist 性能指南深入优化 First Contentful PaintFCP让首屏在 1.8 秒内渲染【免费下载链接】Front-End-Checklist The essential checklist for modern web development, for humans and AI agents项目地址: https://gitcode.com/gh_mirrors/fr/Front-End-Checklist本篇指南以 Front-End-Checklist 仓库中first-contentful-paint规则文档为骨架系统讲解 FCPFirst Contentful Paint首次内容绘制的定义、评分阈值与优化手段并结合作者在该仓库中沉淀的规则实现规则原文、Agent 技能定义与相邻规则render-blocking、streaming-html 等展开源码级佐证。读完你将掌握从渲染原理、关键路径分析到资源加载策略、测量与验证的完整 FCP 优化工作流。FCP 是什么浏览器渲染出第一块内容的时刻First Contentful Paint 标记的是浏览器渲染出第一块内容的时刻——通常是一段文本、一张图片或一个非白色背景的元素。它衡量的是页面开始有东西可看的时间而不是布局完成或完全可交互的时间。规则文档用一条流水线描述了 FCP 的渲染路径HTML → DOM → CSSOM → Render Tree → Paint任何阻塞这条路径的资源都会推迟 Paint 的发生规则明确列出三类主要阻塞源同步 JavaScript解析器遇到script必须下载并执行完毕后才能继续构建 DOMRender-blocking CSS浏览器必须拿到全部 CSS 并构建完 CSSOM 才能决定如何绘制大型 HTML 文档HTML 字节越多DOM 构建完成的时间越长首块内容出现的越晚。在仓库中这条规则被归类为performance/web-vitals子类目见 frontmatter并与largest-contentful-paint、interaction-to-next-paint、cumulative-layout-shift一起构成了 core-web-vitals 清单。也就是说FCP 不是孤立指标而是 Core Web Vitals 体系里衡量加载体验的第一环——LCP 关注最大内容何时可见FCP 则关注第一个内容何时可见。为什么 FCP 重要第一眼反馈决定用户去留FCP 是页面加载给用户的第一个视觉信号。快速的 FCP 让用户确信网站正在响应从而降低感知等待时间和跳出率反之页面长时间空白会让用户误以为网站已崩溃。这正是规则文档中 Why It Matters 的核心论断也是该规则被标记为Priority: high、难度 intermediate、预计耗时 20 分钟的原因见 规则 frontmatter。需要注意的是FCP 与 TTFBTime to First Byte是不同概念TTFB 是服务器响应首字节到达浏览器的时间属于 FCP 的前置环节。规则文档在优化服务器响应时间一节专门处理 TTFB我们在下文会展开。FCP 评分阈值好、中、差的分界线规则文档给出了明确的量化标准这也是日常审计中判断是否达标的直接依据得分评级用户感知0–1.8sGood良好页面响应及时1.8–3sNeeds improvement需改进可感知的延迟 3sPoor较差用户可能放弃配套的 Agent 技能 SKILL.md 把检查动作浓缩为用 Lighthouse 或 PageSpeed Insights 测量 FCP确认首块内容在 1.8 秒内出现并把修复动作归纳为消除渲染阻塞资源、内联关键 CSS、降低服务器响应时间——正好对应下文四个实战小节。消除渲染阻塞资源让关键路径上的请求最少化渲染阻塞资源并不是位于head里的文件这么简单而是任何浏览器在绘制有意义内容之前必须抓取、解析并应用的东西。仓库中专门有一份 render-blocking 规则 对这一主题做了更细的拆解这里结合它给出完整示例。规则文档先展示反面写法!-- Bad: Render-blocking -- head link relstylesheet href/all-styles.css script src/app.js/script /head再给出正确写法内联首屏关键 CSS、用preloadonload延迟非关键 CSS、给 JavaScript 加defer!-- Good: Non-blocking -- head !-- Inline critical CSS -- style /* Critical above-fold styles */ body { margin: 0; font-family: system-ui; } .header { height: 60px; background: #fff; } .hero { min-height: 400px; } /style !-- Defer non-critical CSS -- link relpreload href/styles.css asstyle onloadthis.onloadnull;this.relstylesheet noscriptlink relstylesheet href/styles.css/noscript !-- Defer JavaScript -- script src/app.js defer/script /head针对这个示例render-blocking 规则 补充了几个容易被忽略的要点defer与async并不等价defer保证按文档顺序在解析完成后执行适合有依赖关系的应用代码async下载完立即执行只适合 analytics 这类相互独立的脚本非关键 CSS 的另一种延迟加载手法link relstylesheet href/styles/non-critical.css mediaprint onloadthis.mediaall利用print媒体类型让浏览器异步加载后再切回all反模式用import引入 CSS。import会制造串行发现链一行import就可能把关键路径拉长成多个串行请求反模式给非关键资源加 preload。link relpreload href/chat-widget.js asscript这类可选预加载会与真正重要的资源争夺带宽实际上变相变成渲染阻塞竞争。规则给出的通过标准是首帧绘制路径上只保留渲染首屏有意义内容所必需的资源正常内容路由上阻塞型第三方脚本数量应为 0关键路径上若仍存在嵌套import发现的 CSS即视为不通过。内联关键 CSS首屏样式随 HTML 首包到达内联关键 CSS 的核心思想是把首屏above-the-fold布局与排版所需的最少样式直接写进 HTML 的style避免浏览器在渲染前额外等待一次 CSS 请求往返。规则文档给出的示例就是上一节Good代码块中那个body/.header/.hero的style块。对应该内联多少这个问题render-blocking 规则 给出了明确边界必须留在首屏渲染路径上的首屏布局与排版的极简 CSSLCP 图片或 LCP 文本的样式极少量、路由离开它就无法工作的引导型 JavaScript。可以放心延迟的analytics 及大多数第三方脚本首屏以下区域的 CSS 或组件专属样式聊天组件、评论、轮播、地图等重量级交互代码。同时规则特意警告一个常见误区critical CSS 应当保持critical——把整个样式表全部内联进 HTML 会膨胀首包字节、增加解析成本反而拖慢 FCP。正确做法是只内联首屏所需的最小样式集。自动化生产内联 CSS 时规则文档推荐了critical构建工具// Build tool to extract and inline critical CSS // Using critical package const critical require(critical) critical.generate({ base: dist/, src: index.html, target: index-critical.html, inline: true, width: 1300, height: 900, penthouse: { blockJSRequests: false, }, })参数含义base为站点根目录src/target指定输入输出 HTMLinline: true表示将提取出的关键 CSS 内联进目标文件width/height模拟视口尺寸penthouse是底层使用的关键 CSS 提取引擎选项blockJSRequests: false允许在提取时执行页面 JS 以得到完整渲染结果。Preconnect 与 DNS Prefetch提前建立第三方连接第三方域字体、CDN、分析服务通常不在关键路径的起点但当它们承载首屏所需资源时DNS 查询 TCP/TLS 握手的时间会直接叠加进 FCP。规则文档给出的标准做法head !-- Establish early connections -- link relpreconnect hrefhttps://fonts.googleapis.com link relpreconnect hrefhttps://fonts.gstatic.com crossorigin link relpreconnect hrefhttps://cdn.example.com crossorigin !-- DNS prefetch for less critical origins -- link reldns-prefetch hrefhttps://analytics.example.com /head要点区分preconnect提前完成 DNS TCP TLS 握手适用于确定会在首屏阶段请求的源如字体托管域、主 CDNdns-prefetch只提前解析 DNS开销更小适用于没那么关键或将来才可能请求的源如 analyticscrossorigin属性对需要 CORS 的请求字体、跨域资源必须带上否则 preconnect 的握手无法复用。在仓库中preconnect与dns-prefetch也被收录为独立规则主题见 resource-hints 相关规则目录说明尽早建立连接是该清单体系中一项单独可审计的优化点。优化服务器响应时间TTFB 与 StreamingTTFB 是 FCP 的上游闸门——HTML 首字节到得越晚浏览器能开始解析和绘制的时间就越晚。规则文档给出两层优化第一层缓存降低回源延迟Next.js 示例// Next.js - reduce TTFB with caching // next.config.js module.exports { async headers() { return [ { source: /:path*, headers: [ { key: Cache-Control, value: public, s-maxage3600, stale-while-revalidate86400, }, ], }, ] }, }这条策略使用 CDN 共享缓存s-maxage3600即缓存 1 小时stale-while-revalidate86400过期后 24 小时内允许先返回旧缓存、后台异步刷新让大多数请求命中缓存而不再等待源站计算。第二层Streaming 让首字节更早到达规则文档中的 App Router 示例Suspense包裹动态区域、静态内容立即渲染、动态内容流式注入在仓库的 streaming-html 规则 中有完整展开。它给出的对比数据直观展示了收益传统缓冲式 SSR: 0ms 服务器开始执行 800ms 所有数据库查询完成 820ms TTFB — 首字节到达浏览器 900ms FCP 流式 SSR: 0ms 服务器开始执行 10ms TTFB — shell HTML 立即刷出 10ms 浏览器开始抓取 CSS、发现 LCP 图片 300ms 慢查询完成组件 HTML 流出 380ms FCP — 首屏内容绘制示例中浏览器提前约 790ms 开始工作。核心结论有两点Suspense边界粒度决定成败把整页包进一个Suspense等价于缓冲式 SSR——所有数据就绪前什么都不输出。应围绕每个独立数据获取的区块设置细粒度边界确保首屏内容不被首屏以下的数据阻塞警惕代理缓冲Nginx、Cloudflare 等代理默认会缓冲响应后再转发会抵消 Streaming 的效果需要设置X-Accel-Buffering: no并要求 CDN 对 HTML 响应做透传。字体加载优化避免不可见文本网页字体是 FCP 的隐形杀手——字体文件未就绪时依赖该字体的文本可能完全不渲染FOITFlash of Invisible Text。规则文档给出两手方案预加载关键字体让字体请求尽早发出!-- Preload critical fonts -- link relpreload href/fonts/main.woff2 asfont typefont/woff2 crossorigin 注意asfont与crossorigin是必须的字体请求天然是 CORS 请求缺少crossorigin会导致预加载被浏览器丢弃、重复下载。用font-display: swap避免文本不可见/* Use font-display to avoid blocking text */ font-face { font-family: MainFont; src: url(/fonts/main.woff2) format(woff2); font-display: swap; /* Show fallback text immediately */ }font-display: swap让浏览器立即用回退字体渲染文本字体就绪后再交换从而保证第一个内容按时出现。这与仓库 core-web-vitals 清单 中 Usefont-display: optionalfor web fonts 的建议同属一类思路——核心是绝不让字体文件阻塞文本的首次绘制。React Server Components把首屏渲染放到服务端客户端渲染CSR意味着浏览器必须先下载 JS、执行、再渲染FCP 前有一整段空白等待。规则文档给出的方案是让首屏组件在服务端渲染——服务端组件不携带客户端 JS、无 hydration 延迟内容随 HTML 首包直接可见// Server components render faster - no client JS needed // app/components/Hero.tsx export default function Hero() { // This component renders on server, no hydration delay return ( section classNamehero h1Welcome to Our Site/h1 pContent visible immediately/p /section ) } // app/page.tsx import Hero from ./components/Hero export default function Page() { return ( Hero / {/* Fast FCP - server rendered */} InteractiveSection / {/* Client component, loads after */} / ) }这里的原则可以推广到所有 SSR 框架把 FCP/LCP 候选元素hero 图片、主标题、首屏文本放在服务端渲染的路径上而不是等客户端 fetch 完成后再渲染。仓库的 largest-contentful-paint 规则 用一对正反例强化了这一点——反例中useEffect内 fetch 完数据才返回img页面在数据到达前没有任何 LCP 候选元素正例改为服务端async组件直接渲染图片。测量 FCPweb-vitals 与 Performance API优化必须建立在测量之上。规则文档提供两种测量手段方式一web-vitals 库生产环境真实用户数据// Using web-vitals library import { onFCP } from web-vitals onFCP(metric { console.log(FCP:, metric.value, ms) // Report to analytics if (metric.value 1800) { console.warn(FCP exceeds 1.8s threshold) } })方式二原生 PerformanceObserver无需依赖// Using Performance API const observer new PerformanceObserver(list { for (const entry of list.getEntries()) { if (entry.name first-contentful-paint) { console.log(FCP:, entry.startTime) } } }) observer.observe({ type: paint, buffered: true })两种方式的适用场景不同web-vitals适合在生产环境采集 RUM真实用户监控数据并按 1.8s 阈值告警PerformanceObserver监听paint类型的first-contentful-paint条目适合调试和自研监控。规则文档的 SKILL.md 也特别强调了一条工作纪律在下结论前先用 DevTools、Lighthouse 或字段数据确认真正的瓶颈所在避免凭猜测改错方向。验证与验收自动化 人工双重确认规则文档把验证拆成自动与人工两层自动化检查运行 Lighthouse在 Performance 分区查看 FCP 得分使用 Chrome DevTools Performance 面板分析渲染时间线用网络节流Slow 3G复测慢网场景查看 PageSpeed Insights 获取真实用户字段数据用 WebPageTest 观察详细的瀑布流waterfall请求时序。这些工具在仓库的 streaming-html 规则 中给出了更具体的量化验收建议Lighthouse 中 TTFB 应低于 600ms绿色、FCP 应低于 1.8sDevTools Network 面板中页面响应应以多个 chunk 到达而不是一次性complete。人工检查在节流的目标设备或浏览器配置上手动确认用户可见的最终效果确保优化确实改善了真实体验——实验室分数高不等于真实用户快规则文档对此特别强调。关联规则地图FCP 在性能体系中的位置在仓库的规则体系中FCP 不是孤立存在它与多个相邻规则构成完整优化链路建议按此顺序协同审计关联规则与 FCP 的关系仓库路径Eliminate render-blocking resources消除关键路径上的 CSS/JS 阻塞是 FCP 最直接的优化手段packages/content/rules/en/performance/render-blocking.mdxStream HTML通过流式 SSR 压低 TTFB让首块 HTML 更早到达packages/content/rules/en/performance/streaming-html.mdxOptimize largest contentful paintFCP 关注第一个内容LCP 关注最大内容二者常被一并审查packages/content/rules/en/performance/largest-contentful-paint.mdxCore Web Vitals 清单将 FCP 与 LCP、CLS、INP 组成完整体检清单packages/content/checklists/en/core-web-vitals.mdx如果你的场景是Agent 辅助审计仓库还为每条规则生成了对应的 Agent 技能文件first-contentful-paint/SKILL.md其中aiContext字段明确指导在审计缓慢页面加载、重型资源或渲染延迟时启用此技能并先通过 DevTools、Lighthouse 或字段数据确认瓶颈再推荐改动——这与本文所有实战步骤背后的方法论完全一致。小结一份可执行的 FCP 优化清单把规则文档与仓库源码内容汇总成最终行动清单测量先行用 Lighthouse / PageSpeed Insights / web-vitals 确认 FCP 是否超过 1.8s并定位瓶颈环节TTFB、资源发现、传输或渲染压缩关键路径内联首屏关键 CSS非关键 CSS 用preloadonload或mediaprint延迟加载JavaScript 一律defer/async消灭import链提前建连对关键第三方源preconnect次要源dns-prefetch压低 TTFB用 CDN 缓存 stale-while-revalidate减少回源用 Streaming 细粒度Suspense让 shell HTML 立即刷出字体不阻塞preload关键字体 font-display: swap首屏走服务端渲染把 hero、主标题等 FCP/LCP 候选元素交给 Server Components 或 SSR避免客户端 fetch 延迟渲染验证闭环自动化跑 Lighthouse/PageSpeed Insights/WebPageTest人工在节流设备上复核真实体验。按这套流程执行你的首屏内容就有明确依据地逼近 1.8 秒的Good门槛。【免费下载链接】Front-End-Checklist The essential checklist for modern web development, for humans and AI agents项目地址: https://gitcode.com/gh_mirrors/fr/Front-End-Checklist创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考