加载第一个字节所需时间 (TTFB)

浏览器支持

  • 43
  • 12
  • 31
  • 11

来源

首字节时间 (TTFB) 是一项基本指标,用于在实验室和现场衡量连接设置时间和网络服务器响应能力。它测量的是从请求资源到响应的第一个字节开始到达所经过的时间。这有助于识别 Web 服务器何时因速度过慢而无法响应请求。对于导航请求(即对 HTML 文档的请求),它先于其他有意义的加载性能指标。

网络请求时间图表。这些阶段从左到右依次为:重定向、Service Worker Init、Service Worker Fetch 事件、HTTP 缓存、DNS、TCP、请求、早期提示 (103)、响应(与卸载提示重叠)、处理和加载。关联的时间包括 redirectStart、redirectEnd、fetchStart、domainLookupStart、domainLookupEnd、connectStart、secureConnectionStart、connectEnd、requestStart、interimResponseStart、responseStart、unloadEventStart、unloadEventEnd、responseEnd、domInteractive、domContentLoadedEventStart、domContentLoadedEventEnd、domComplete、loadEventStart 和 loadEventEnd。
网络请求阶段及其关联时间的示意图。TTFB 测量 startTimeresponseStart 之间的所用时间。

TTFB 是以下请求阶段的总和:

  • 重定向时间
  • Service Worker 启动时间(如果适用)
  • DNS 查找
  • 连接和 TLS 协商
  • 请求,直到响应的第一个字节到达

缩短连接设置时间和后端的延迟时间有助于降低 TTFB。

TTFB 得分是多少?

由于 TTFB 发生在以用户为中心的指标(例如首次内容绘制 (FCP)Largest Contentful Paint (LCP))之前,因此我们建议您的服务器足够快速地响应导航请求,以便第 75 百分位的用户遇到“良好”阈值内的 FCP。一般来说,大多数网站都应尽量将 TTFB 控制在 0.8 秒以内。

良好的 TTFB 值为 0.8 秒或更短,不良值大于 1.8 秒,两者之间的任何值都需要改进
良好的 TTFB 值为 0.8 秒或更短,不良值大于 1.8 秒。

要点:由于 TTFB 不是核心网页指标指标,因此网站并不是绝对必须具有出色的 TTFB,只要较长的 TTFB 不会使您的网站更难在重要指标上获得较高的得分。在优化加载时间时,请考虑您的网站传送内容的方式。如果某个网站快速提供初始标记,然后不得不等待脚本填充有意义的内容(如单页应用 [SPA] 通常就是这种情况),那么较低的 TTFB 尤为重要。另一方面,对于由服务器渲染的网站,不需要太多客户端工作,即使其 TTFB 更高,FCP 和 LCP 值也会比客户端渲染的网站更高。

如何衡量 TTFB

您可以通过以下方式在实验室现场测量 TTFB。

野外工具

实验工具

使用 JavaScript 测量 TTFB

您可以使用 Navigation Timing API 测量浏览器中导航请求的 TTFB。以下示例展示了如何创建一个 PerformanceObserver,用于监听 navigation 条目并将其记录到控制台中:

new PerformanceObserver((entryList) => {
  const [pageNav] = entryList.getEntriesByType('navigation');

  console.log(`TTFB: ${pageNav.responseStart}`);
}).observe({
  type: 'navigation',
  buffered: true
});

web-vitals JavaScript 库也可以在浏览器中以较低的复杂性测量 TTFB:

import {onTTFB} from 'web-vitals';

// Measure and log TTFB as soon as it's available.
onTTFB(console.log);

衡量资源请求量

TTFB 适用于所有请求,而不仅仅是导航请求。特别是,在设置与跨源服务器上的连接时,托管的资源可能会造成延迟。如需测量字段中资源的 TTFB,请在 PerformanceObserver 中使用 Resource Timing API

new PerformanceObserver((entryList) => {
  const entries = entryList.getEntries();

  for (const entry of entries) {
    // Some resources might have a responseStart value of 0 if they're being
    // cached, or if a cross-origin resource is served without a
    // Timing-Allow-Origin header set.
    if (entry.responseStart > 0) {
      console.log(`TTFB: ${entry.responseStart}`, entry.name);
    }
  }
}).observe({
  type: 'resource',
  buffered: true
});

上述代码段与用于测量导航请求的 TTFB 的代码段类似,只不过前者不是查询 'navigation' 条目,而是查询 'resource' 条目。此外,它还考虑到了这样一个事实:如果连接已经打开,或者系统即时从缓存中检索到了某个资源,则从主源加载的某些资源可能会返回 0 值。

如何改进 TTFB

如需有关改进网站的 TTFB 的指导,请参阅关于优化 TTFB 的深度指南。