npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

radar-analytic-performance

v0.1.5

Published

**性能监测插件**

Downloads

100

Readme

Radar Analytics JS SDK:performance 集成文档(2022.07.08)

性能监测插件

本功能是基于radar-analytic-js-sdk的插件功能实现的。对页面进行性能方面的指标采集。目前正在快速迭代中。

SDK接入

NPM

npm是JavaScript 的包管理工具,可以安装、共享、分发代码,管理项目依赖关系,关于npm的安装和使用可以参考官方文档.

npm i radar-analytic-performance
import RADAR_MONITOR from "radar-js-analytic-sdk";
import "radar-analytic-performance";

//初始化sdk
RADAR_MONITOR.setProject("QH_11_1552");
//初始化性能监测和配置各个指标开启,默认指标采集是true。
RADAR_MONITOR.use("performance", {
  clsEnable: true, 
  fidEnable: true,
  lcpEnable: true,
  fcpEnable: true,
  ttfbEnable: true,
  fpEnable: true,
  navigation_timingEnable: true,
  ttiEnable: true
});

验证上报

使用Chrome DevTools验证上报

打开Chrome DevTools, 选择 Networks, 查看 Request Method 为 GET 的请求

上报域名为: http://s.360.cn/qdas/p.htm

上报格式

| 参数 | 说明 | 示例 | | :---------| :----------- | :----------- | | u | 当前页面地址 |http://yunpan.360.cn| | gid |当前用户唯一ID,最后一组为用户访问次数计数器,倒数第二组为本次访问的开始时间|233721054.382655244.1457698147282.1478749461964.8717| | sid | 当前会话ID,最后一组为本次会话中访问次数计数器。会话默认为30分钟,可以通过setActiveTime来修改 |233721054.2725755090674145300.1478748424279.6074| | p | 项目代号,在开发者信息管理平台中注册网站时自动分配 |QH_1_7| | title | 网页标题 |Web开发者使用指南| | mid | 第1个参数ID的值 |123456| | t | 时间戳,无意义,避免浏览器缓存 | 1332742970052 | | _indicators| 性能指标 | cls、fcp、fid、ttfb、lcp、navigation_timing、tti | | _value | 指标值 | 31.100000000093132 | | isCustom | 是否为自定义指标 | false |

性能指标

如何计算 TTI 指标

可交互时间(TTI)是测量加载响应度的重要实验室指标。该指标有助于识别看起来具备交互性但实际上并非如此的页面情况。迅捷的TTI有助于确保页面的有效性。 本文指标介绍部分引用自 https://web.dev/tti/

什么是 TTI 指标

TTI(Time To Interactive),即从页面加载开始到页面处于完全可交互状态所花费的时间。页面处于完全可交互状态时,满足以下3个条件: 1、页面已经显示有用内容。 2、页面上的可见元素关联的事件响应函数已经完全注册。 3、事件响应函数可以在事件发生后的50ms内开始执行。

很多情况下,开发者往往只关注页面渲染相关的指标,如FP、FCP等,而忽视了页面的可用性指标。TTI即是反应页面可用性的重要指标。TTI值越小,代表用户可以更早地操作页面,用户体验就更好。

images

如何获取TTI指标

算法描述

Long Task定义:在浏览器主线程执行时间超过50ms的Task。

静默窗口定义:窗口所对应的时间内没有Long Task,且进行中的网络请求数不超过2个。

1、从起始点(一般选择FCP或FMP)时间开始,向前搜索一个不小于5s的静默窗口期。 2、找到静默窗口期后,从静默窗口期向后搜索到最近的一个Long Task,Long Task的结束时间即为TTI。 3、如果没有找到Long Task,以起始点时间作为TTI。 4、如果2、3步骤得到的TTI < DOMContentLoadedEventEnd,以DOMContentLoadedEventEnd作为TTI。 参考如下示意图(图中的First Consistently Interactive 即为TTI):

images

浏览器兼容性说明

TTI指标要求浏览器支持Long Tasks APIResource Timing API

如何优化TTI指标

如需了解如何改进某个特定网站的TTI,您可以运行一次Lighthouse性能审计,并留心查看审计建议的各种具体机会。 如需了解改进TTI的常见方式(针对任何网站),请参阅以下性能指南: 优化:缩小JavaScript体积 [优化:预链接到所需的来源](https://web.dev/uses-rel-preconnect) 优化:预加载关键请求 优化:减少第三方代码的影响 优化:最小化关键请求深度 优化:减少JavaScript执行时间 优化:最小化主线程工作 优化:保持较低的请求数和较小的传输大小

参考资料

  • https://docs.google.com/document/d/1GGiI9-7KeY3TPqS3YT271upUVimo-XiL5mwWorDUD4c
  • https://web.dev/tti

如何计算 Navigation Timing 指标

它提供了可用于衡量一个网站性能的数据。与用于相同目的的其他基于JavaScript的机制不同,它可以提供更有用和更准确的端到端延迟数据。你可以衡量之前难以获取的数据,如卸载前一个页面的时间,在域名解析上的时间,在执行load(en-US)事件处理器上花费的总时间等。

images

各字段解释

images

初始化阶段

  • redirectStart:页面重定向时的开始时间(如果存在重定向的话)或者是0
  • redirectEnd:如果存在重定向的话,redirectEnd表示最后一次重定向后服务端response的数据被接收完毕的时间。否则的话就是0.

请求阶段

  • fetchStart:浏览器发起资源请求时,如果有缓存,则返回读取缓存的开始时间。
  • domainLookupStart:查询DNS的开始时间。如果请求没有发起DNS请求,如keep-alive,缓存等,则返回fetchStart的时间点。
  • domainLookupEnd:查询DNS的结束时间。如果没有发起DNS请求,如keep-alive,缓存等,则返回fetchStart的时间点。
  • connectStart:当浏览器开始与服务器连接时的时间。如果没有建立连接,如请求是keep-alive、缓存等,那么它的值等同于domainLookupEnd。
  • secureConnectionStart:如果页面使用HTTPS,它的值是安全链接握手之前的时刻。如果该属性不可用,则返回undefined。如果该属性可用,但没有使用HTTPS,则返回0。
  • connectEnd:当浏览器端完成与服务端建立连接的时刻。如果没有建立连接,如请求是keep-alive、缓存等,那么它的值等同于domainLookupEnd。
  • responseStart:指客户端收到从服务端(或缓存、本地资源)相应回的第一个字节的数据时刻。
  • responseEnd:指客户端收到服务端(或缓存、本地资源)响应回的最后一个字节的数据时刻。

解析渲染阶段

  • domInteractive:浏览器完成对所有HTML的解析并且DOM构建完成的时间点,是DOM准备就绪的时间点。
  • domContentLoaded:DOM准备就绪并且没有样式表阻止JavaScript执行的时间点,可以开始构建渲染树,一般表示DOM和CSSOM均准备就绪的时间点。
  • domComplete:顾名思义,所有处理完成,并且网页上的所有资源(图像等)都已下载完毕,也就是说,加载转环已停止旋转,表示网页及其所有子资源都准备就绪的时间点。
  • loadEventStart:作为每个网页加载的最后一步,浏览器回触发onload事件,以便触发额外的应用逻辑。
  • loadEventEnd:onload事件执行完成。

许多JavaScript框架都会等待onload事件发生后,才开始执行它们自己的逻辑。因此,浏览器会捕获loadEventStartloadEventEnd时间戳,让我们能够追踪执行所花费的时间。

各阶段计算公式

经过上面各个字段的解释,可以清晰得出以下:

  • Redirect:redirectEnd - redirectStart

计算条件:redirectEnd非0且redirectStart非0

  • DNS:domainLookupEnd - domainLookupStart

计算条件:domainLookupEnd非0且domainLookupStart非0

  • TCP:connectEnd - connectStart

计算条件:connectEnd非0且connectStart非0

  • SSL:connectEnd - secureConnectionStart

计算条件:connectEnd非0且secureConnectionStart非0

  • Request:responseStart - requestStart

计算条件:responseStart非0且requestStart非0

  • Response:responseEnd - responseStart

计算条件:responseEnd非0且responseStart非0

  • DomReady:domContentLoaded - fetchStart

计算条件:domContentLoaded非0且fetchStart非0

  • DomParse:domInteractive - responseEnd

计算条件:domInteractive非0且responseEnd非0

  • resourceLoad:loadEventStart - domContentLoaded

计算条件:loadEventStart非0且domContentLoaded非0

参考资料

如何计算 FP 和 FCP 指标

FP(First Paint)

首次渲染的时间点。 在性能统计指标中,从用户开始访问 Web 页面的时间点到 FP 的时间点这段时间可以被视为 白屏时间,也就是说在用户访问 Web 网页的过程中,FP 时间点之前,用户看到的都是没有任何内容的白色屏幕,用户在这个阶段感知不到任何有效的工作在进行 所以通常会反映页面的白屏时间,而白屏时间会反映当前 Web 页面的网络加载性能情况,当加载性能非常良好的情况下,白屏的时间就会越短,用户等待内容的时间就会越短,流失的概率就会降低。

FCP(First Contentful Paint)

首次有内容渲染的时间点。 在性能统计指标中,从用户开始访问 Web 页面的时间点到 FCP 的时间点这段时间可以被视为 无内容时间,也就是说在用户访问 Web 网页的过程中,FCP 时间点之前,用户看到的都是没有任何实际内容的屏幕,用户在这个阶段获取不到任何有用的信息。 所以通常会反映页面的首次出现内容的时间,而首次出现内容时间会反映当前 Web 页面的网络加载性能情况、页面 DOM 结构复杂度情况、inline script 的执行效率的情况,当所有的阶段性能做的非常好的情况下,首次出现内容的时间就会越短,用户等待的时间就会越短,流失的概率就会降低 首次内容绘制 (FCP) 指标测量页面从开始加载到页面内容的任何部分在屏幕上完成渲染的时间。对于该指标,"内容"指的是文本、图像(包括背景图像)、<svg>元素或非白色的<canvas>元素。 FP与FCP这两个指标之间的主要区别是:FP是当浏览器开始绘制内容到屏幕上的时候,只要在视觉上开始发生变化,无论是什么内容触发的视觉变化,在这一刻,这个时间点,叫做FP。 相比之下,FCP指的是浏览器首次绘制来自DOM的内容。例如:文本,图片,SVG,canvas元素等,这个时间点叫FCP。 images

怎样算是良好的 FCP 分数?

为了提供良好的用户体验,网站应该努力将首次内容绘制推荐时间控制在1.8 秒或以内。为了确保您能够在大部分用户的访问期间达成建议目标值,一个良好的测量阈值为页面加载的第 75 个百分位数,且该阈值同时适用于移动和桌面设备。

如何获取指标

通过 W3C Paint Timing 规范草案 中的描述, PerformancePaintTiming 中包含当前 Web 页面的绘制性能打点信息,可通过 performance.getEntriesByType('paint') 方法获取, FP和 FCP 就在其中.

  • 找到 name 为 first-paint 的对象,描述的即为 FP 的指标数据,其中 startTime 即为 FP 时间。如下图所示:

images

  • 找到 name 为 first-contentful-paint 的对象,描述的即为 FCP 的指标数据,其中 startTime 即为 FCP 时间。如下图所示:

images

浏览器兼容性说明

指标要求浏览器支持 Paint Timing API

如何优化FCP指标

优化:消除阻塞资源 优化:缩小 CSS 优化:移除未使用的CSS 优化:预连接到所需的来源 优化:减少服务端响应时间(TTFB) 优化:避免多个页面重定向 优化:预加载关键请求 优化:避免巨大的网络负载 优化:如何使用高效缓存策略去缓存静态资源 优化:避免 DOM 过大 优化:最小化关键请求深度 优化:确保文本在网页字体加载期间保持可见 优化:保持较少的请求数以及较小的传输大小

参考文章

https://web.dev/fcp https://github.com/berwin/Blog/issues/46

如何计算LCP指标

最大内容绘制 (LCP) 是测量感知加载速度的一个以用户为中心的重要指标,因为该项指标会在页面的主要内容基本加载完成时,在页面加载时间轴中标记出相应的点,迅捷的 LCP 有助于让用户确信页面是有效的。

本文指标解释的内容引用自 https://web.dev/lcp

指标解释

LCP(Largest Contentful Paint )

最大内容绘制 (LCP) 指标会根据页面首次开始加载的时间点来报告可视区域内可见的最大图像或文本块完成渲染的相对时间。

images

哪些元素在考量范围内?

根据当前最大内容绘制 API中的规定,最大内容绘制考量的元素类型为:

  • <img>元素

  • 内嵌在<svg>元素内的<image>元素

  • <video>元素(使用封面图像)

  • 通过url()函数(而非使用CSS 渐变)加载的带有背景图像的元素

  • 包含文本节点或其他行内级文本元素子元素的块级元素

何时报告最大内容绘制?

Web页面通常是分阶段加载的,因此,页面上最大的元素可能会发生变化。例如,在一个带有文本和图像的页面上,浏览器最初可能只是呈现文本,而此时浏览器会分派一个largest-contentful-paint entry。稍后,图像完成加载完成,会分派第二个largest-contentful-paint entry。

images

web.dev 给出的推荐时间是 2500ms,可以根据您站点的自身特性来适当调整。

指标获取实现细节

创建一个 PerformanceObserver ,使用 Largest Contentful Paint API 监听并上报。具体的结算时机可以参考下文的代码实现

new PerformanceObserver((entryList) => {
    for (const entry of entryList.getEntries()) {
        console.log('LCP candidate:', entry.startTime, entry);
    }})
.observe({type: 'largest-contentful-paint', buffered: true});

浏览器兼容性说明

指标要求浏览器支持 Largest Contentful Paint APIPerformanceObserver,sdk引用polyfill来支持chrome、Firfox、Safari浏览器。理论上也可能支持chrome内核浏览器。

如何优化LCP指标

LCP主要受四个因素影响:

  • 缓慢的服务器响应速度

如需深入了解如何改进LCP,请参阅优化LCP。有关其他能够改进LCP的单个性能技巧的进一步指导,请参阅:

  • 优化您的图像
  • 优化网页字体
  • 优化您的JavaScript(针对客户端渲染的网站)
### 其他资源
* [安妮·沙利文 (Annie Sullivan)](安妮·沙利文 (Annie Sullivan))在[performance.now()](https://youtu.be/ctavZT87syI)上发表的演讲:[《从 Chrome 的性能监测工具中吸取的教训》](https://anniesullie.com/)(2019)

如何计算CLS指标

重要词汇: 累积布局偏移 (CLS) 是测量视觉稳定性的一个以用户为中心的重要指标,因为该项指标有助于量化用户经历意外布局偏移的频率,较低的 CLS 有助于确保一个页面是令人愉悦的

本文指标解释的内容引用自 https://web.dev/cls

CLS指标介绍(Cumulative Layout Shift)

CLS 测量整个页面生命周期内发生的所有意外布局偏移中最大一连串的布局偏移分数。 每当一个可见元素的位置从一个已渲染帧变更到下一个已渲染帧时,就发生了布局偏移 。(有关单次布局偏移分数计算方式的详细信息,请参阅下文。)

CLS 分数如何计算?

浏览器在计算分布偏移分数时,会查看可视区域大小和两个已渲染帧之间的可视区域中不稳定元素的位移。布局偏移分数是该位移的两个度量的乘积:影响分数和距离分数(两者定义如下)。


布局偏移分数 = 影响分数 * 距离分数 

影响分数

影响分数测量不稳定元素对两帧之间的可视区域产生的影响。 前一帧和当前帧的所有不稳定元素的可见区域集合(占总可视区域的部分)就是当前帧的影响分数。

images

在上图中,有一个元素在一帧中占据了一半的可视区域。接着,在下一帧中,元素下移了可视区域高度的25%。红色虚线矩形框表示两帧中元素的可见区域集合,在本示例中,该集合占总可视区域的75%,因此其影响分数为0.75.

距离分数

布局偏移分数计算公式的另一部测量不稳定元素相对于可视区域位移的距离。距离分数指的是任何不稳定元素在一帧中位移的最大距离(水平或垂直)除以可视区域的最大尺寸维度(宽度或高度,以较大者为准)。

images

在上方的示例中,最大的可视区域尺寸维度是高度,不稳定元素的位移距离为可视区域的25%,因此距离分数为0.25。 所以,在这个示例中,影响分数是0.75,距离分数是0.25,所欲布局偏移分数是0.75*0.25=0.1875。

  • 最初,布局偏移分数只根据影响分数进行计算。引入距离分数是为了避免在大元素发生微小位移的情况下进行过度惩罚的情况。

预期布局偏移 vs.意外布局偏移

布局偏移并不总是坏事。事实上,许多动态网络应用程序经常更改页面元素的起始位置。

由用户发起的布局偏移

布局偏移只有在用户并不期望其发生时才算是坏事。换言之,对用户交互(单击链接、点选按钮、在搜索框中键入信息等)进行响应的布局偏移通常没有问题,前提是偏移发生的时机与交互时机足够接近,使用户对前后关系一目了然。 例如,如果某次用户交互触发了一个网路请求,而该请求可能需要一段时间才能完成,那么最好立即留出一些空间并显示加载指示器,避免在请求完成时出现令用户不快的布局偏移。如果用户没有意识到当前正在加载某些内容。或者不知道资源什么时候能够准备就绪。他们就可能会在等待期间尝试点击其他内容(来打破僵局)。 在用户输入500毫秒内发生的布局偏移会带有hadRecentInput标志,便于在计算中排出这些偏移。

  • 小心: hadRecentInput标志仅适用于不连续输入事件,如轻触、点击或按键操作。滚动、拖动或捏拉缩放手势等连续性交互操作不算作"最近输入"。更多详情请参阅布局不稳定性规范

怎样算才是良好的CLS分数?

为了提供良好的用户体验,网站应该努力将CLS分数控制在0.1或以下。为了确保您能够在大部分用户的访问期间达成建议目标值,一个良好的测量阈值为页面加载的第75个百分位数,且该阈值同时适用于移动和桌面设备。

images

指标获取实现细节

Layout Shift 是由Layout Instability API 定义的,当视图中可见的元素在两个帧之间改变其起始位置时,该API就会报告布局偏移项。这些元素被认为是不稳定元素。创建一个PerformanceObserver,使用Layout Instability API 来监听意外的布局变化。

let clsValue = 0;
let clsEntries = [];
let sessionValue = 0;
let sessionEntries = [];
new PerformanceObserver((entryList) => {
    for (const entry of entryList.getEntries()) {
        // Only count layout shifts without recent user input.
        if (!entry.hadRecentInput) {
            const firstSessionEntry = sessionEntries[0];
            const lastSessionEntry = sessionEntries[sessionEntries.length - 1];
        // If the entry occurred less than 1 second after the previous entry and      
        // less than 5 seconds after the first entry in the session, include the      
        // entry in the current session. Otherwise, start a new session.  
         if (sessionValue
         && entry.startTime - lastSessionEntry.startTime < 1000
         && entry.startTime - firstSessionEntry.startTime < 5000) {
             sessionValue += entry.value;
             sessionEntries.push(entry);
          } else {
              sessionValue = entry.value;
              sessionEntries = [entry];
           }
           // If the current session value is larger than the current CLS value
           // update CLS and the entries contributing to it.
           if (sessionValue > clsValue) {
               clsValue = sessionValue;
               clsEntries = sessionEntries;
               // Log the updated value (and its entries) to the console. 
               console.log('CLS:', clsValue, clsEntries)
           }
       }
}}).observe({type: 'layout-shift', buffered: true});

浏览器兼容性说明

指标要求浏览器支持Layout Instability API 和 PerformanceObserver。sdk引用polyfill来支持chrome、Firfox、Safari浏览器。理论上也可能支持chrome内核浏览器。

如何优化CLS指标

常用方法有:

  • 在图片和视频元素中包含大小属性,或者用CSS长宽比框之类的东西保留所需的空间。
  • 不要在现有内容之上插入内容,除非是为了响应用户交互。
  • 多用tramsform annimations,而不是触发布局变化的annimations properties。

深入了解CLS优化

优化Cumulative Layout Shift 累积布局偏移

优化:调试布局偏移

参考文档

https://web.dev/cls/

如何计算FID指标

首次输入延迟(FID)是测量加载响应度的一个以用户为中心的重要指标,因为该项指标将用户尝试与无响应页面进行交互的体验进行了量化,低FID有助于让用户确信页面是有效的

本文指标的部分内容介绍引用自 https://web.dev/fid

什么是FID指标

Long Task 定义:在浏览器主线程执行时间超过 50ms 的 Task。

Input Delay:输入延时,记录用户和页面进行交互操作,所花费的时间。例如,从用户点击一个按钮,到浏览器正确处理这个按钮的行为,并反馈给用户所花费的时间。通常情况下,Input Delay 是因为浏览器主线程在忙于执行其他操作,无暇处理用户的交互操作。

FID(First Input Delay)测量从用户第一次与页面交互(例如当他们单击链接、点按钮或使用由JavaScript驱动的自定义控件)直到浏览器对交互作出响应,并实际能够开始处理事件处理程序所经过的时间。

FID发生在FCP和TTI之间,因为这个阶段虽然页面已经显示出部分内容,但尚不具备完全的可交互性。这个阶段用户和页面交互,往往会有较大延迟。如下图所示,浏览器接受到用户输入操作时,主线程正在忙于执行一个Long Task,只有当这个Task执行完成后,浏览器才能响应用户的输入操作。

images

尽管任何输入的延迟都会破坏用户体验,我们只选取FID作为通用指标是以下原因:

1、FID反映用户对页面交互性和响应性的第一印象,良好的第一印象有助于用户建立对整个应用的良好印象。 2、页面加载阶段,资源的处理任务最重,也最容易产生输入延迟。因此关注FID指标对提升页面的可交互性有更大收益。 3、FID和页面加载完成后的Input Delay 具有不同的解决方案。针对FID,我们一般建议通过Code Splitting 等方式减少页面加载阶段JS的加载、解析和执行时间。而页面加载完成的Input Delay,通常是由于开发人员代码编写不当,引起JS执行时间过长而产生的。

怎样算是良好的FID分数?

为了提供良好的用户体验,网站应该努力将首次输入延迟控制在100毫秒或以内。为了确保您能够在大部分用户的访问期间达成建议目标值,一个良好的测量阈值为页面加载的第75个百分位数,且该阈值同时适用于移动和桌面设备。

web.dev 给出的FID指标的推荐时间是100ms,可以根据您站点的自身特性来适当调整。

指标计算

FID指标

FID的计算需要用户真实操作页面,可以借助Event Timing API 进行测量。创建PerformanceObserver对象,监听fist-input事件后,利用Event Timing API,通过事件的开始处理时间,减去事件的发生时间,即为FID。 因为FID的值严重依赖用户触发操作的时机,所以我们需要考虑FID值的分布曲线。一般情况下,建议采用95分位的指标值,这能反应最差的用户交互体验对应的FID值。

如何优化FID指标

要了解如何改进某个特定网站的FID,您可以运行一次Lighthouse性能审计,并留心查看审计建议的各种具体机会。 虽然FID是一项实际指标(而灯塔是一个实验室指标工具),但改进FID的指导方向与改进总阻塞时间(TBT)这项实验室指标的指导方向相同。 如需深入了解如何改进FID,请参阅优化FID。有关其他能够改进FID的单个性能技巧的进一步指导,请参阅:

优化:减少第三方代码的影响 优化:减少JavaScript执行时间 优化:最小化主线程工作 优化:保持较少的请求数以较小的传输大小

如何计算TTFB指标

Time to Fist Byte(TTFB)是衡量实验室和现场链接设置时间和Web服务器响应能力的基本指标。有助于识别Web服务器何时响应请求太慢。在导航请求(即对HTML文档的请求)的情况下,优先于所有其他有意义的加载性能指标。

什么是TTFB?

TTFB是衡量资源请求于响应的第一个字节开始到达之间时间的指标。

images

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

  • Redirect time (重定向时间)
  • Service worker startup time (if applicable) (Service work 启动时间)
  • DNS lookup (DNS查询)
  • Connection and TLS negotiation(连接和TLS协商)
  • Request,up until the point at which the first byte of the response has arriced(请求直到响应的第一个字节到达)

减少链接建立时间和后端的延迟将有助于降低TTFB。

怎么算是良好的TTFB分数?

由于网络状况和应用程序后端程序实现的差异很大,所以不能在“良好”TTFB分数上放置任意的数字。因为TTFB优先于以用户为中心的指标,如First Contentful Paint (FCP)和maximum Contentful Paint (LCP),所以建议您的服务器对导航请求的响应足够快,以便75%的用户在“良好”阈值内体验FCP。

指标获取实现细节

创建一个PerformanceObserver,使用Navigation Timing API监听导航请求并上报。具体结算时机可以参考下文的代码实现。

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

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

TTFB适用于所有请求,特别是跨域服务器上的资源可能会由于需要建立与这些服务器的连接而引入延迟。要测量资源的TTFB,可以用Resource Timing API来进行监听。

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

  for (const entry of entries) {
    // Some resources may have a responseStart value of 0, due
    // to the resource being cached, or a cross-origin resource
    // being 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对资源进行指标化,可能会出现0的情况。原因是资源链接已经打开或者资源从缓存中获取。

如果跨域服务器未能设置Timing-Allow-Origin标头,那么跨域请求的 TTFB 将无法在字段中测量。

浏览器兼容性说明

指标要求浏览器支持Resource Timing API 和 Navigation Timing API。sdk引用polyfill来支持chrome、Firfox、Safari浏览器。理论上也可能支持chrome内核浏览器。

如何优化TTFB指标

偏高TTF值可能是以下原因:

  • 服务器资源不足,处于高流量负载

通常选择具有基础设施的合适托管提供商来最小化TTFB,以确保高运行时间和响应能力。这与cdn结合会有所帮助。

使用Server-Timing API收集有关应用程序后端进程性能的附加字段数据。这可以帮助识别可能被忽视的改进机会。

改善高TTFB时间和相关感知延迟的其他机会包括:

参考文档

https://web.dev/ttfb/