【免费下载链接】Front-End-Checklist
🗂 The essential checklist for modern web development, for humans and AI agents
本篇文章基于 Front-End-Checklist 项目中的
resource-hints规则(skills/resource-hints/references/rule.md,同时维护于 packages/content/rules/en/performance/resource-hints.mdx),系统讲解四种资源提示(Resource Hint)的使用场景、决策规则、框架落地方式与验证手段。读完本文,你将能够在真实页面中判断"该不该加提示、给哪个资源加、加哪一种",并借助 Lighthouse、PageSpeed Insights 与网络瀑布图验证改动是否真正生效。
规则概览:这到底是什么,什么时候该用它
resource-hints是 Front-End-Checklist 中归入performance(性能)分类、loading(加载)子分类的高优先级规则,其核心一句话是:实现 preload、prefetch、preconnect 提示,以优化资源加载优先级。规则元数据给出的执行成本为优先级high、难度intermediate、预估耗时20 分钟(见 packages/content/rules/en/performance/resource-hints.mdx 的 frontmatter)。
规则适用的典型场景是:审计页面加载缓慢、资源过重、渲染延迟。规则配套的 AI 上下文(aiContext)明确要求:在推荐任何改动之前,先通过 DevTools、Lighthouse 或真实用户数据(field data)确认瓶颈所在——资源提示不是万能药,只有命中真正的瓶颈才有价值。
对应技能的快速参考(skills/resource-hints/SKILL.md)给出了四句核心准则:
- 用
preload加载首屏关键资源(字体、Hero 图片); - 用
preconnect连接第三方源(CDN、API、分析服务); - 用
prefetch预取下一次导航可能用到的资源; - 用
dns-prefetch作为preconnect的轻量级替代。
规则的 frontmatter 同时给出一个项目侧的性能数据:资源提示让浏览器更早发起关键资源请求,平均可使LCP 提升 100–300ms(whyItMatters字段)。需要强调的是,这是规则在项目内的自我描述,实际收益取决于页面瓶颈是否真的出在"发现资源太晚"这一环节。
为什么值得关注:浏览器"发现得太晚"是根本问题
规则正文开门见山:资源提示只在"浏览器发现资源太晚"时才有效。web.dev 的 Learn Performance 指南与 Patterns.dev 的 preload/prefetch 指南都强调同一个观点——只有当提示加速了"正确的资源、正确的时间",它才有价值。
围绕这一前提,规则总结了四条"为什么重要"的理由:
- 更早发现真正关键的资源:
preload能让 Hero 图片、字体或路由关键 CSS 更早进入网络请求队列; - 减少浪费的往返(round-trip):
preconnect可以把少量已知外部源的 DNS、TCP、TLS 握手从关键路径中移除; - 后续操作更顺滑:
prefetch让"下一个最可能的路由或交互"感觉上是即时响应; - 滥用代价高昂:每一个多余的 preload、prefetch 或 preconnect 都会与更重要的任务竞争带宽、连接套接字与解析器注意力——因此任何提示改动之后,都值得用 PageSpeed Insights 复查一遍。
换句话说:不加提示的损失是"慢一点",加错提示的损失是"抢了关键资源的带宽",后者往往更严重。这与规则引用的决策依据一致:错误地提前提示某个资源,可能比完全不加提示更糟。
四种资源提示与决策规则:一张表讲清楚
规则的核心决策表是全文的精华,完整继承如下。它给出了每种提示的适用对象、应回避的对象以及实践中的数量上限:
| 提示类型 | 用在哪里 | 避免用于 | 实践上限 |
|---|---|---|---|
preload | 当前路由中首屏或 LCP 需要、但被发现得太晚的资源 | 未来路由的资源、低优先级组件、已被足够早发现的资源 | 通常每路由<= 3-5个 preload |
prefetch | 下一路由或下一次交互"很可能"用到、但当前不必须的资源 | 当前路由的关键资源;在下一步不确定时用于带宽敏感用户 | 只覆盖最可能的几个导航目标 |
preconnect | 确定很快需要的源,尤其是首屏路由上的字体、媒体 CDN 或 API | 投机性的第三方、或很久之后才会用到的源 | 通常<= 2-4个源 |
dns-prefetch | 置信度较低的外部源,此时建立完整连接为时过早 | 已经在关键路径上、理应享受完整preconnect的源 | 作为轻量兜底,不要当成默认配置 |
同类规则 packages/content/rules/en/performance/preconnect.mdx 为preconnect补充了更细的决策规则,两者可对照阅读:
- 只有当某个源在当前路由上"确定需要"、且很可能在首屏前后被用到时,才使用
preconnect; - 当某个源"可能但不保证"被用到时,优先使用
dns-prefetch; - 每页的
preconnect数量控制在约2-4个高价值源; - 对字体及其他走 CORS 获取的资源,务必带上
crossorigin属性。
实战示例:四种提示的正确写法与反模式
1. Preload 当前路由真正需要的关键资源
preload用于"当前路由、首屏或 LCP 需要、但浏览器发现得太晚"的资源。典型目标有两个:LCP 候选的 Hero 图片(它藏在 CSS 背景或列表深处,浏览器要到很晚才发现)和通过 CSS 间接发现的字体:
<head> <!-- Good: hero image is the likely LCP candidate --> <link rel="preload" href="/images/hero.webp" as="image" type="image/webp" fetchpriority="high" > <!-- Good: route-critical font discovered late through CSS --> <link rel="preload" href="/fonts/inter-latin.woff2" as="font" type="font/woff2" crossorigin > </head>注意其中每个属性的作用:
as="image"/as="font":声明资源类型,浏览器据此决定优先级队列与请求头;type="image/webp":声明 MIME 类型,供浏览器判断当前环境是否支持(不支持则跳过);fetchpriority="high":显式提升该请求的抓取优先级(这也是同仓库独立规则 fetchpriority-attribute 的主题);crossorigin:字体以 CORS 方式获取,缺失该属性会导致请求被重复发起(先发一次普通请求,再发一次 CORS 请求)。
2. Prefetch 下一个最可能的步骤,而不是当前页面
prefetch的目标是"下一个最可能发生的导航",例如电商页面上用户大概率会进入的结算页及其脚本:
<head> <!-- Good: likely next navigation --> <link rel="prefetch" href="/checkout"> <link rel="prefetch" href="/static/checkout.js" as="script"> <!-- Bad: current-route critical CSS should be loaded normally or preloaded --> <link rel="prefetch" href="/styles/home.css" as="style"> </head>反例是注释标注的/styles/home.css:当前路由的关键 CSS 应该正常加载或preload,而不是被降级成低优先级的prefetch——这会让首屏样式来得更慢。同一思路也适用于"prefetch 你自己正在访问的页面",那不会改善发现顺序,只会增加噪声。
3. Preconnect 只连"立刻就要用"的源,其余交给 dns-prefetch
preconnect提前完成 DNS、TCP、TLS 握手,适合"首屏确定会用"的外部源——Google 字体、图片 CDN、首屏 API:
<head> <!-- Good: fonts are used in the first viewport --> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <!-- Good: image CDN serves the hero media --> <link rel="preconnect" href="https://images.example-cdn.com" crossorigin> <!-- Better than preconnect for speculative vendors --> <link rel="dns-prefetch" href="https://analytics.example.com"> </head>两个细节值得强调:fonts.gstatic.com用于提供字体文件本身(CORS 请求),因此必须带crossorigin;而分析服务这类"可能用到但不保证"的源,用dns-prefetch(只解析 DNS、不开完整连接)比preconnect更划算。
4. 反模式:Too Much Too Soon(过早、过量)
规则给出了一个"教科书级反面教材":一口气 preload 三个字体 + 三个脚本,再对四个投机性第三方源全部 preconnect。其后果是提示之间互相竞争,反而把带宽、套接字与解析器注意力从真正关键的资源上夺走:
<head> <!-- Bad: too many preloads compete with each other --> <link rel="preload" href="/fonts/a.woff2" as="font" crossorigin> <link rel="preload" href="/fonts/b.woff2" as="font" crossorigin> <link rel="preload" href="/fonts/c.woff2" as="font" crossorigin> <link rel="preload" href="/carousel.js" as="script"> <link rel="preload" href="/reviews.js" as="script"> <link rel="preload" href="/chat-widget.js" as="script"> <!-- Bad: speculative origins do not deserve early socket setup --> <link rel="preconnect" href="https://chat.example.com"> <link rel="preconnect" href="https://ads.example.com"> <link rel="preconnect" href="https://social.example.com"> </head>聊天、评论、广告这类"交互后才可能用到"的第三方源,几乎永远不该出现在首屏的关键路径上(详见 preconnect.mdx 的 Common Mistakes 一节)。
框架落地:HTML、Vite、Next.js 与 React 的四种写法
规则文档按框架给出了完整的落地示例(对应 MDX 源文件中的CodeTabs结构)。HTML / Vite的做法是在index.html的<head>中手写提示标签:
<!-- HTML --> <head> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preload" href="/fonts/inter-latin.woff2" as="font" type="font/woff2" crossorigin> </head><!-- Vite:index.html --> <head> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preload" href="/fonts/Inter.woff2" as="font" type="font/woff2" crossorigin> </head>Next.js在根布局(app/layout.tsx)的<head>中声明,注意 React 环境下crossorigin写作驼峰属性crossOrigin="anonymous":
import type { ReactNode } from 'react' export default function RootLayout({ children }: { children: ReactNode }) { return ( <html lang="en"> <head> <link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" /> <link rel="preload" href="/fonts/Inter.woff2" as="font" type="font/woff2" crossOrigin="anonymous" /> </head> <body>{children}</body> </html> ) }React(配合 react-helmet)则适合把提示放到具体页面的<Helmet>中,实现"按页面精准注入"——例如在定价页预取用户最可能点击的注册页:
import { Helmet } from 'react-helmet' function PricingPage() { return ( <Helmet> <link rel="prefetch" href="/signup" /> <link rel="prefetch" href="/static/signup.js" as="script" /> </Helmet> ) }仓库自身的实现印证:next/font 自动化的资源提示
值得一提的是,本仓库自己的站点(apps/web应用)并没有在layout.tsx中手写字体 preconnect——这是因为 apps/web/app/layout.tsx 使用next/font/google声明了Sora、Public_Sans、Fira_Code三套字体,并统一设置display: 'swap'。从源码结构可以推断:Next.js 会在构建期下载字体并自托管,自动生成对应的字体preload与按字符子集切分的样式,因此既不需要为fonts.googleapis.com手动加 preconnect,也天然规避了 FOIT(字体引起的不可见文本闪烁)。这正是"用框架机制取代手写提示"的现代化实践——当工具链已经替你完成了 preload 时,再手动叠加提示反而会违背本规则"宁缺毋滥"的原则。
常见错误清单
规则汇总了五个高频错误,可作为自查 checklist:
- preload 了当前路由用不到的资源:这会把带宽从 CSS、字体和 LCP 资源上偷走;
- prefetch 自己正在访问的页面:不改善发现顺序,只是增加噪声;
- preconnect 了过多源:为每个厂商都开套接字,浪费连接预算和电量;
- 忘记
as或crossorigin属性:错误的属性会降低优先级判定的准确性,甚至触发重复请求(典型即字体缺失crossorigin); - 跳过测量:资源提示只有在瀑布图确实按预期变化时才有价值。
验证与度量:改动之后必须做的两件事
规则把验证拆成自动化与手动两个层面。
自动化检查(Automated Checks)
- 在 Lighthouse、PageSpeed Insights 或 DevTools 中测量受影响页面或流程,确认目标指标确实提升;
- 检查网络瀑布图(waterfall)或性能时间线,确认预期的资源获取或执行变化真的发生了。
对preconnect场景,preconnect.mdx 还补充了可用的工具与审计项:Lighthouse 内置的"preconnect-to-required-origins"审计、PageSpeed Insights、DevTools Performance 面板(观察早期套接字连接)、WebPageTest 的 Waterfall 图(观察 DNS/TCP/TLS 是否提前完成)。
手动检查(Manual Checks)
- 在限速的移动端配置下验证改动,而不是只看本地桌面环境;
- 如果该规则映射到了性能预算或 Web Vital,确认页面现在能稳定保持在阈值之内。
关联规则与进一步阅读
resource-hints并非孤立规则。它的 frontmatter 声明了四个常被一起评审的关联规则,全部位于performance/loading区域:lazy-loading(懒加载,两者常配合决定"哪些资源该延后")、lazy-above-fold(首屏以上资源不得懒加载)、fetchpriority-attribute(fetchpriority 属性与 preload 协同控制抓取优先级)、third-party-scripts(第三方脚本加载策略)。做资源提示审计时,建议将这一组规则放在同一轮评审中,避免"提示与懒加载互相打架"。
仓库内的深入阅读入口:
- 规则完整版(含决策表与代码示例):skills/resource-hints/references/rule.md 与 packages/content/rules/en/performance/resource-hints.mdx
- 技能元数据与快速参考:skills/resource-hints/SKILL.md
- 姊妹规则:preconnect 深度版 packages/content/rules/en/performance/preconnect.mdx、fetchpriority 属性规则 packages/content/rules/en/performance/fetchpriority-attribute.mdx
- 仓库自身字体加载的现代化实现:apps/web/app/layout.tsx
小结:把"提示"当作一种需要预算的优化
资源提示的本质是对浏览器发现机制的一种补偿:只在"浏览器发现得太晚"时出手,只对"当前路由确定需要"的资源出手,并且时刻控制总量(preload 每路由 3-5 个、preconnect 每页 2-4 个源)。规则文档反复强调的测量闭环(改动 → 瀑布图验证 → 移动端限速复查)才是决定资源提示成败的最后一步——不加提示页面慢 100ms,加错提示页面可能慢更多。按照本文的决策表逐项对照、落码、测量,你就能把 preload、prefetch、preconnect 与 dns-prefetch 用到刀刃上。
【免费下载链接】Front-End-Checklist
🗂 The essential checklist for modern web development, for humans and AI agents
相关推荐
Front-End-Performance-Checklist资源预加载:preload、prefetch、preconnect详解
Front End Performance Checklist资源预加载:preload、prefetch、preconnect详解 前端性能优化是提升用户体验
前端Front-End-Checklist 实战:用 preload、prefetch、preconnect、dns-prefetch 资源提示为浏览器抢跑关键资源
Front End Checklist 实战:用 preload、prefetch、preconnect、dns prefetch 资源提示为浏览器抢跑关键资源
Front-End-Checklist 前端性能指南:preload、prefetch、preconnect 与 dns-prefetch 资源提示(Resource Hints)完整实战
Front End Checklist 前端性能指南:preload、prefetch、preconnect 与 dns prefetch 资源提示(Resou
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考