core-web-vitals-large-sites-hostlist.html
< BACK 昏暗的数据中心走廊,复古的服务器机架沐浴在琥珀色LED灯光和电影般的阴影中

大型网站的核心网页指标:如何达到1.5秒以下的LCP

回到2022年,一个托管比较网站出现在我的收件箱里。大型目录——约4,000个页面,深度嵌套的分类结构,到处都是联盟链接,英雄图像大得像小大陆一样。他们的Google Search Console简直是一场噩梦。LCP在移动设备上停留在4.2秒。INP(当时仍被称为FID)勉强。这个客户已经花了6,000英镑与前一家代理机构合作,他们只是添加了CDN就收工了。

那个项目最终塑造了我们在Seahawk对高页面数量网站的性能思考方式——目录网站、列表平台、像HostList风格构建的托管评测网站。下面是实际的操作手册。Seahawk for high-page-count sites — directory sites, listing platforms, hosting review properties like HostList-style builds. What follows is the actual playbook.

---

为什么大型网站的LCP问题不同

小型网站有简单的问题。一个英雄图像、一个主题、一个插件做太多事情。修复这三样东西,你就可以在2秒以内了。

大型网站?完全是另一回事。LCP 元素会根据你访问的页面而改变。分类存档的 LCP 候选与产品详情页不同,产品详情页与首页也不同。大多数性能工具报告单一分数。这个数字是谎言——它是一个差异巨大的页面集合的平均值,修复首页而忽视它下面的 3,800 个列表页面,这正是代理机构如何毁坏声誉的方式。which page you're on. A category archive has a different LCP candidate than a product detail page, which has a different candidate than the homepage. Most performance tools report a single score. That number is a lie — it's an average of a wildly varied set of pages, and fixing the homepage while ignoring the 3,800 listing pages underneath it is exactly how agencies earn bad reputations.

Google 的核心网页指标文档明确指出,现场数据——真实用户体验,通过 Chrome 用户体验报告测量——才是 Google 实际用于排名信号的内容。PageSpeed Insights 的实验室数据是方向性的,不是决定性的。我见过网站在 PSI 上获得 95 分,但在 CrSX 数据中仍然有不良的 LCP。不要混淆两者。Core Web Vitals documentation from Google is clear that field data — what real users experience, measured in Chrome User Experience Report — is what Google actually uses for ranking signals. Lab data from PageSpeed Insights is directional, not definitive. I've seen sites score 95 on PSI and still have Poor LCP in CrSX data. Don't confuse the two.

列表网站上的三个真实罪魁祸首

在我审计过的每个大型网站上(到目前为止我已经审计了数百个),LCP 失败几乎总是归结为三个根本原因:

  • 未优化的英雄图像或卡片图像——通常以全分辨率提供、格式错误、没有 fetchpriority 提示 — often served at full resolution, wrong format, no fetchpriority hint
  • 渲染阻塞的第三方脚本——附属链接追踪器、广告网络、比较小部件在浏览器能绘制任何东西之前加载 — affiliate trackers, ad networks, comparison widgets loading before the browser can paint anything
  • TTFB 占用 LCP 预算——缓慢的服务器响应在页面甚至开始加载之前消耗 600–900ms — slow server response eating 600–900ms before the page even starts loading

第三个是人们低估的。如果你的 TTFB 是 700ms,在浏览器渲染单个像素之前,你已经花费了近一半的"良好" LCP 预算。托管选择和服务器端缓存不是 DevOps 关注点——它们是 SEO 关注点。

---

从 TTFB 开始:这首先是一个托管和缓存问题

我上面提到的那个HostList类型的项目?我做的第一件事是从五个不同的地理位置运行WebPageTest。TTFB始终在680–820ms之间。该网站托管在弗吉尼亚州的共享主机上。他们的大部分有机流量来自英国和德国。WebPageTest from five different geographic locations. TTFB was consistently 680–820ms. The site was on a shared host in Virginia. Most of their organic traffic came from the UK and Germany.

将他们迁移到在伦敦和法兰克福有边缘节点的托管WordPress主机。配置全页缓存,列表页面的缓存生命周期为12小时(数据本来就不经常变化)。TTFB在重复请求上降至120–180ms,在首次缓存未命中时为280–350ms。这单一的改动在我优化任何图片之前就让LCP缩短了大约500ms。

关于托管方面,我总是检查以下几点:

  1. 全页缓存是否真的在工作?检查X-Cache响应头。如果每个请求都显示MISS,说明你的缓存层没有正常运作。 Check the X-Cache response header. If it says MISS on every single request, your caching layer isn't functioning.
  2. 源服务器地理位置是否靠近你的主要受众?这听起来很明显。但你会惊讶于这一点多么经常出错。 This sounds obvious. You'd be surprised how often it's wrong.
  3. 是否启用了keep-alive?一些便宜的主机仍然禁用持久连接。在2024年这样做很离奇,但确实会发生。 Some cheaper hosts still disable persistent connections. Wild in 2024, but it happens.
  4. HTTP/2或HTTP/3是否活跃?运行curl -I --http2 https://yourdomain.com并检查响应中的协议。 Run curl -I --http2 https://yourdomain.com and check the protocol in the response.

在解决TTFB之前不要动图片优化。在一个慢速服务器上优化图片就像给一栋着火的房子粉刷一样。

---

LCP图片问题(以及为什么`fetchpriority`改变了一切)

对。图片。在卡片网格布局的列表网站上,LCP 元素几乎总是首屏上方的第一张卡片图片——或者 hero 横幅。浏览器必须发现它、获取它、解码它,然后渲染它。这些步骤中的每一步都可能被延迟。

以下是我们在 HostList 项目中实际所做的,按顺序:

  1. 使用 Imagify 的批量转换,将所有卡片图片转换为 WebP——平均文件大小在不影响我们使用的卡片缩略图尺寸(280×180px 显示,为视网膜屏幕以 2 倍像素比例提供)视觉质量的情况下下降了 58%。 — using Imagify's bulk conversion. Average file size dropped 58% without visible quality loss at the card thumbnail sizes we were using (280×180px display, served at 2x for retina).
  2. 给第一张卡片图片添加 `fetchpriority="high"`——这个改动本身就在 WebPageTest 的测量中让 LCP 减少了约 200ms。浏览器停止将其视为常规懒加载图片,而是立即在预加载扫描器中排队。 — This one change alone knocked ~200ms off measured LCP in WebPageTest. The browser stops treating it like a regular lazy image and queues it immediately in the preload scanner.
  3. 从前两行卡片图片中移除 `loading="lazy"`——懒加载对于下方区域的图片效果很好。但在首屏可见行中,它会对你产生负面影响。它告诉浏览器在图片接近视口时才去获取它——而图片此时已经在视口中了。 — Lazy loading is brilliant for below-fold images. On the first visible row, it actively hurts you. It tells the browser to not fetch the image until it's near the viewport — which it already is.
  4. 在首页模板的 `<head>` 中为 hero 图片添加了 `<link rel="preload">` 标签。 in the <head> on the homepage template specifically.

这个流程把首页的 LCP 从 3.1 秒降低到了 1.4 秒(在实验条件下)。现场数据在大约 28 天内跟进(这大约是 CrUX 数据在大规模反映变化所需的时间)。

关于响应式图片的说明

如果你向移动设备提供相同的 1400px 宽的图片,你在浪费带宽并增加解码时间。正确使用 srcset。我知道这听起来像是 2016 年的话题,但我仍然在大约 40% 通过 Seahawk 的网站上看到这种情况。WordPress 的 wp_get_attachment_image() 函数会自动生成 srcset——但前提是图片上传时分辨率足够高,且主题没有通过 add_filter('max_srcset_width', ...) 抑制它。srcset properly. I know this sounds like a 2016 conversation but I still see it on probably 40% of the sites that come through Seahawk. The WordPress wp_get_attachment_image() function generates srcset automatically — but only if the image was uploaded at sufficient resolution and the theme hasn't suppressed it with add_filter('max_srcset_width', ...).

---

阻塞渲染的脚本:联盟网站的税收

主机比较网站和列表平台靠联盟收入运营。这意味着第三方追踪脚本。Commission Junction、Impact、Awin、自定义像素追踪器——它们堆积起来。我在一个列表网站上数过14个独立的第三方脚本源。每一个都需要单独的DNS查询、TCP连接和TLS握手,然后才能收到该脚本的一个字节。

解决方案不是删除这些脚本。你办不到——收入取决于它们。解决方案是排序。

没有第三方脚本应该阻塞LCP元素的初始渲染。句号。

在实际操作中,这意味着:

  • 将所有联盟/分析脚本移到DOMContentLoaded事件之后加载,而不是在<head>中。after the DOMContentLoaded event, not in <head>.
  • 在你控制的每个脚本上使用async或defer属性。async or defer attributes on every script you control.
  • 对于你不控制的脚本(由标签管理器注入),用defer加载Google Tag Manager本身——是的,这对大多数联盟追踪用例来说是安全的,GTM自己的文档也认可这种方法。defer — yes, this is safe for most affiliate tracking use cases, and GTM's own documentation acknowledges this approach.
  • 使用Asset CleanUp Pro或WP Rocket的脚本延迟功能等脚本管理器,将非必要的第三方脚本延迟加载到用户交互(首次滚动或首次点击)时。

在HostList.io重建中,延迟第三方脚本将总阻塞时间从1,840ms减少到290ms。TBT本身不是Core Web Vital,但它与INP的相关性很强,而INP是。is.

---

字体加载:那个无人谈论的 LCP 隐形杀手

自定义字体会引发特定的故障模式。浏览器渲染你的布局,到达 LCP 文本元素(有时 LCP 是标题而非图像),然后在绘制前等待字体文件。这称为不可见文本闪烁,它会根据字体文件大小和服务器距离延迟 LCP 200ms 到超过一秒。

两件事可以解决这个问题:

  • 在 @font-face 声明中使用 font-display: swap — 浏览器立即用后备字体渲染,自定义字体加载后替换。LCP 候选元素按时绘制。 in your @font-face declaration — the browser renders in a fallback font immediately and swaps when the custom font loads. LCP candidate gets painted on time.
  • 自托管你的字体。Google Fonts 会增加跨域请求。使用 google-webfonts-helper 工具自托管,你可以从自己的域名提供字体,节省额外的连接。google-webfonts-helper tool lets you serve fonts from your own domain, cutting that extra connection.

我用那个工具在大约 45 分钟内把一个大型目录网站从 Google Fonts 迁移出来。LCP 改进了 180ms。单独看不是革命性的,但结合其他所有优化,这些边际收益会复合增长。

---

衡量实地中真正重要的指标

CrUX 数据是基础事实。但它只按月更新,且仅适用于流量足够的 URL。对于拥有数千个页面的大型网站,你需要更细粒度的数据。

我使用 PageSpeed Insights API 对代表性的 URL 样本进行脚本化测试——通常是按流量排名前 100 的页面、50 个分类级别页面和 20 个"薄"深度目录页面。每月运行一次可以获得合适的性能分布,而不是单点评分。PageSpeed Insights API scripted across a representative sample of URLs — typically the top 100 pages by traffic, 50 category-level pages, and 20 "thin" deep-catalogue pages. Running this monthly gives a proper performance distribution, not a single-point score.

在 Lighthouse CI 中(我们在为具有开发周期的客户的 CI/CD 管道中运行),我们对以下指标进行断言:

  • LCP ≤ 2.5s(实验室,保守目标,因为实测字段通常比实验室落后 10–15%)
  • TBT ≤ 300ms
  • CLS ≤ 0.1

但老实说——对于目标是 LCP 低于 1.5s 的 HostList 类型的构建,实验室目标需要更严格。我们在 Lighthouse CI 中为这些项目设置 LCP ≤ 1.8s,一旦 CrUX 跟上,通常会在实测字段中产生 1.3–1.5s 的成绩。

---

汇总:HostList 的结果

在运行完上述所有步骤——主机迁移、整页缓存、图像格式转换、LCP 候选项上的 fetchpriority、移除首屏行的懒加载、脚本延迟加载和字体自托管——数字是这样的:fetchpriority on LCP candidates, lazy-load removal from above-fold rows, script deferral, and font self-hosting — here's what the numbers looked like:

  • TTFB: 780ms → 160ms(中位数,英国访客): 780ms → 160ms (median, UK visitors)
  • LCP(实验室,移动端):4.2s → 1.4s: 4.2s → 1.4s
  • LCP(实际,CrUX,75 百分位):3.8s → 1.6s(迁移后 60 天测量): 3.8s → 1.6s (measured 60 days post-migration)
  • TBT:1,840ms → 290ms: 1,840ms → 290ms
  • CLS:原本就不错,为 0.03,未改变: was already fine at 0.03, unchanged

并非每个网站都能获得 2.8 秒的提升。但我做过的几乎所有大型列表网站都同时存在这些问题,这意味着收益是叠加的。修复一个问题你能获得 300ms 的提升。全部修复你就能获得 2.5 秒。

---

常见问题

托管服务对 LCP 的影响真的那么大吗?

是的——可能比最初的任何其他因素都重要。如果你的 TTFB 超过 500ms,再多的图片优化也无法让你达到"良好"的 LCP。TTFB 是其他一切的基础。先把它控制在 200ms 以下,然后再考虑其他的。

我应该使用 CDN 而不是迁移主机吗?

CDN 有助于静态资源交付,如果配置得当,可以降低缓存整页 HTML 的 TTFB。但许多 CDN 设置只缓存资源,不缓存整个 HTML 响应。检查你的 CDN 是否真的在提供缓存的 HTML,还是只在卸载图像。如果是后者,更好的源主机对 LCP 的改进会更大。

`fetchpriority="high"` 现在得到广泛支持了吗?

截至 2024 年,是的——它在 Chrome、Edge 和 Safari(自 Safari 17.2 起)中受支持。Firefox 支持在 Firefox 132 中推出。对于不支持它的浏览器,该属性会被安全地忽略。在你的 LCP 图像元素上添加它没有任何缺点。

CrUX 数据需要多长时间才能反映改进?

从真实用户开始体验网站更快版本起,大约需要 28 天。CrUX 使用滚动 28 天窗口。所以如果你今天部署更改,你的字段数据分数在大约一个月后才会完全反映这些改变。如果在优化冲刺的第二天 PageSpeed Insights 仍然显示"需要改进",不用惊慌。

对于列表网站,单一最高影响力的改变是什么?

在几乎每个项目上,都是 TTFB。但第二高的一直是从首屏卡片图像上移除 `loading="lazy"` 并添加 `fetchpriority="high"`。这两项改变通常占总 LCP 改进的 40–60%。其他一切都是在这个基础上的复合收益。loading="lazy" from above-fold card images and adding fetchpriority="high". Together those two things usually account for 40–60% of the total LCP improvement. Everything else is compounding gains on top of that foundation.

---

大型网站的性能工作主要是管道维护工作。乏味、有条不紊,但当你把 4 秒的 LCP 降到 1.4 秒,两个月后看到自然流量提升时,深感满足。没有单一的魔法设置——只是一系列按正确顺序做出的具体决策。

让服务器变快。然后让 LCP 元素被及早发现和获取。然后让其他一切都为它让路。

< BACK