🤯由 性能指标 散发开来的 Performance API 被问爆了呀

前言

前段时间面wxg总算是见识到了啥叫要求高了,疯狂被问『是怎么做的?』「为什么这么做?」「你了解过它的底层原理吗?」😫真的被问裂开了,没学的不知道,学了的记不住🤯顾不住工作的疲劳了,加班给自己系统整理下知识链路吧hai🙃

正篇

本文结构计划为:性能指标介绍 -> Lighthouse 性能指标Core Web Vitals 的指标 对比 -> 深入了解Performance API -> 性能指标是怎么计算出来的 -> 应用场景粗略介绍 ->

性能指标介绍

先来看下Lighthouse中有哪些核心性能指标

指标 介绍
FCP 首次有内容渲染 First Contentful Paint 在性能统计指标中,从用户开始访问页面的时间点FCP的时间点这段时间可以被视为无内容时间,也就是说中用户访问Web页面的过程中,FCP时间点之前,用户看到的都是没有任何内容的屏幕,在这个阶段获取不到任何有用的信息。
LCP 最大内容渲染 Largest Contentful Paint LCP表示用户开始访问页面的时间点可视区域内可见的最大(尺寸)图片或文本块完成渲染的相对时间。相对于FCP测量初始DOM内容完成渲染所需的时间,但无法捕获页面上最大内容渲染所需的时间,LCP更能体现屏幕可视区元素渲染的用户体验,因为最大的内容通常也是最有意义的。LCP在2.5秒内达到快速级别。
TBT 总阻塞时间 Total Blocking Time 页面加载过程中,主线程被长时间任务(通常是 JavaScript 执行)阻塞的总时间。
CLS 累积布局偏移 Cumulative Layout Shift 页面加载过程中发生的意外布局变化的总量,可能导致用户在交互时误触或出现不良体验。
SI 速度指数 Speed Index 用于衡量页面可视区域内容填充的速度,它是页面可视区域内容填充花费的平均时间,通常3.4秒内可达快速等级。

后续在阅读一些 Lighthouse 指标相关文章的时候发现,好像每次展现出来的指标不是固定的,并且还有另外一套衡量网页用户体验 的核心指标体系:"Core Web Vitals", 有意思,一起来研究下这两套体系有啥区别。

体系比对

  • "Core Web Vitals" 是谷歌提出的用于衡量网页用户体验的核心指标体系 ,主要聚焦于网页的加载性能、交互响应和视觉稳定性

  • "Lighthouse" 是谷歌开发的网页性能检测工具 ,其性能指标体系与 Core Web Vitals(CWV)既有重叠又有差异,是开发者的 "诊断工具",面向技术优化

一、Lighthouse 性能指标与 Core Web Vitals 的指标对比

  1. Core Web Vitals(CWV)核心指标
指标 类型 核心关注点 属于 Lighthouse 吗?
LCP 加载性能 主内容可见速度 是(性能报告中包含)
FID 交互响应 首次操作延迟 是(性能报告中包含)
CLS 视觉稳定性 布局偏移程度 是(性能报告中包含)
  1. Lighthouse 性能指标体系(更全面)
指标分类 具体指标 与 CWV 的关系
加载性能 LCP、FCP、TTFB、TTI LCP 是 CWV 核心,FCP/TTFB/TTI 为辅助
交互响应 FID、长任务(Long Tasks) FID 是 CWV 核心,长任务影响 FID
视觉稳定性 CLS 与 CWV 完全一致
资源效率 总阻塞时间(TBT)、JavaScript 执行时间 影响 FID 和 TTI
字节效率 首次加载字节数、重复访问字节数 影响 LCP 和整体加载速度
渲染效率 主线程利用率、样式计算时间 影响 FCP 和 LCP

二、核心区别:指标的 "聚焦度" 与 "用途" 不同

  1. CWV:用户体验的 "核心门槛",面向普通用户和搜索引擎
  • 特点:仅包含 3 个最关键指标(LCP/FID/CLS),直指用户对网页的三大核心体验痛点:

    • LCP:"能不能快速看到内容"
    • FID:"点了有没有反应"
    • CLS:"页面会不会乱跳"
  • 目的

    • 作为谷歌搜索排名的参考因素,推动网站优化基础体验;
    • 用极简指标让非技术人员也能理解网页体验好坏。
  1. Lighthouse 性能指标:开发者的 "诊断工具",面向技术优化
  • 特点:包含 20+ 细分指标,覆盖从加载、渲染到交互的全流程,例如:

    • FCP(首次内容绘制) :比 LCP 更早监测页面初始视觉反馈,定位首屏渲染问题;
    • TTI(可交互时间) :衡量页面完全可操作的时间,比 FID 更全面;
    • TBT(总阻塞时间) :分析 JavaScript 阻塞主线程的时长,直接影响 FID 和 TTI。
  • 目的

    • 为开发者提供详细的性能瓶颈定位,例如 "LCP 慢" 可能由 TTFB 长、图片未优化等多种原因导致,Lighthouse 会细分到具体环节;
    • 支持自定义评分规则(如可调整指标权重),适应不同业务场景的优化需求。

三、为什么要这样分类?------ 从 "用户体验" 和 "技术实现" 双维度理解

  1. CWV 的分类逻辑:以 "用户直觉体验" 为核心
  • 用户不会关心 "TTFB 是 200ms 还是 300ms",但能直观感受到 "页面加载慢""点按钮没反应""广告突然挤掉内容"。
  • CWV 用最简化的指标将技术参数转化为用户可感知的体验,降低理解门槛,同时通过搜索引擎排名强制推动行业优化基础体验。
  1. Lighthouse 的分类逻辑:以 "技术诊断" 和 "全链路优化" 为目标
  • 开发者需要知道 "问题出在哪":例如 LCP 慢,可能需要分析 TTFB(服务器问题)、FCP(渲染问题)、资源加载顺序(代码问题)等细分指标。
  • Lighthouse 的多层级指标体系如同 "性能解剖图",既能定位表层问题(如 LCP 超时),又能深入技术细节(如某个 JavaScript 函数阻塞了主线程),帮助开发者制定精准优化方案。

四、两者的关系:CWV 是 Lighthouse 的 "子集",但定位不同

  • 包含关系:CWV 的 3 个指标均来自 Lighthouse 性能报告,但 Lighthouse 提供了更丰富的上下文数据。

  • 互补关系

    • 非技术人员(如产品经理)可通过 CWV 快速判断网页体验好坏;

    • 开发者则需结合 Lighthouse 全指标分析,例如:

      • 若 LCP 超时,需查看 FCP、TTFB、资源加载瀑布图等定位原因;
      • 若 FID 过高,需分析长任务、JavaScript 执行时间等细分指标。

五、总结:分类的本质是 "目标用户与场景的差异化"

维度 Core Web Vitals Lighthouse 性能指标
目标用户 产品经理、运营、普通用户、搜索引擎 开发者、性能优化工程师
核心价值 定义 "好体验" 的最低标 提供 "如何优化" 的全流程诊断工具
指标数量 3 个极简指标 20+ 细分指标
应用场景 评估、排名、市场竞争 开发、调试、技术优化

这种分类方式既满足了大众对 "用户体验" 的直观认知,又为技术优化提供了精细化的操作空间,形成了从 "体验评估" 到 "技术实现" 的完整闭环。

插个题外知识:非指标的性能(页面流畅度)还可以用什么来衡量呢?

--游戏玩家也许会比较熟悉:「帧率(FPS)」直观感受不同帧率的体验:

  • 50~60FPS:相当流畅,让人倍感舒适。
  • 30~50FPS:因各人敏感程度不同,舒适度因人而异。
  • 30FPS以下:让人感觉到明显的卡顿和不适感。

在Chrome 的 devtools 中我们可以执行 Cmd+Shift+P 输入 show fps 来快速打开fps面板。

页面性能这一块真的好多内容可以聊,到这里还没完呢,要学就学个彻底(不然面试遇到拷打就跟坐牢一样)--- Performance API来了解一下。

深入了解Performance API

啥是PerformanceAPI?

  • PerformanceAPI是浏览器提供的一组用于获取网页性能数据的工具 ,用于精确度量、控制、增强浏览器的性能表现,使测量网站性能达到前所未有的精度
    *

    功能特性
    • 高精度时间测量 :提供高精度的时间戳,如performance.now()方法,单位为毫秒,精度可达微秒,相比Date.now(),它不受系统时间调整的影响,能更精准地测量代码执行时间。
    • 详细性能信息获取 :通过performance.timing属性,可以获取详细的页面加载阶段的时间数据,帮助开发者了解页面加载的每个阶段,如 DNS 查询、资源下载等,快速定位性能瓶颈。
    • 资源加载监控performance.getEntriesByType()方法可获取资源加载的详细信息,例如图片、脚本等文件的加载时间,便于识别加载缓慢的资源,从而进行针对性优化。
    • 自定义性能标记和测量performance.mark()performance.measure()方法允许开发者在代码中标记特定的点,并测量这些点之间的时间间隔,精确定位性能瓶颈。
    常用接口及作用
    • PerformanceTiming 接口:提供更详细的页面加载时间信息,包括各个阶段的开始和结束时间,是测量页面性能的重要接口。
    • PerformanceNavigation 接口:提供有关页面导航的信息,如重定向次数、是否通过缓存加载等,帮助开发者了解页面导航过程中的性能指标。
    • PerformanceEntry 接口:提供有关特定资源或事件的详细性能信息,如资源加载时间、事件处理时间等,用于监控和分析特定资源或事件的性能。
    应用场景
    • 优化代码执行时间 :通过在代码的关键部分使用performance.now()performance.mark()performance.measure()等方法,可以测量代码的执行时间,找出耗时较长的部分,进行针对性的优化。
    • 优化页面加载速度 :利用performance.timingperformance.getEntriesByType()等接口获取页面加载和资源加载的性能数据,找出加载时间较长的资源,采取启用 CDN、代码分割、优化图片等措施来加速页面加载。
    • 监控用户交互性能:可以在用户进行交互操作(如点击按钮、滚动页面等)时,使用 Performance API 记录相关的时间数据,了解用户与网页的交互体验,发现并解决交互过程中存在的性能问题。

了解完啥是Performance,现在可以来关注一下PerformanceTiming接口的详细字段,来上图⬇️

字段名 意义
navigationStart 浏览器准备开始导航到页面的起始时间。 若通过点击链接、书签或表单提交等方式导航,此值为用户操作触发的时间; 若是通过脚本(如 location.href)导航,则为脚本执行的时间。
unloadEventStart 前一个页面(如通过重定向或 history.back() 访问的页面)的 unload 事件开始的时间。 若无前一个页面或前一个页面未触发 unload 事件,则值为 0
unloadEventEnd 前一个页面的 unload 事件结束的时间。 若无前一个页面或前一个页面未触发 unload 事件,则值为 0
redirectStart 第一个 HTTP 重定向开始的时间。 若没有重定向(或重定向非同源),则值为 0
redirectEnd 最后一个 HTTP 重定向完成的时间(即响应的最后一个字节接收完毕)。 若没有重定向(或重定向非同源),则值为 0
fetchStart 浏览器开始获取资源(如 HTML、JSON 等)的时间。 若存在重定向,此值为最后一次重定向后开始获取资源的时间。
domainLookupStart DNS 查询开始的时间。 若使用缓存或本地解析(如 localhost),则此值等于 fetchStart
domainLookupEnd DNS 查询完成的时间。 若使用缓存或本地解析,则此值等于 fetchStart
connectStart TCP 连接开始的时间。 若使用持久连接(如 HTTP/2)或连接已建立,则此值等于 domainLookupEnd
secureConnectionStart TLS/SSL 握手开始的时间。 若请求非 HTTPS 协议或使用持久连接,则值为 0
connectEnd TCP 连接(及 TLS 握手,若适用)完成的时间。
requestStart 浏览器向服务器发送 HTTP 请求的开始时间(即请求的第一个字节发出)。
responseStart 浏览器从服务器接收 HTTP 响应的开始时间(即响应的第一个字节收到)。
responseEnd 浏览器接收完响应的最后一个字节的时间。
domLoading 浏览器开始解析 HTML 文档的时间(即 document.readyState 变为 'loading')。
domInteractive 浏览器完成 HTML 解析并开始构建 DOM 树的时间(即 document.readyState 变为 'interactive')。此时,DOM 树已构建完成,但外部资源(如脚本、样式表、图片)可能仍在加载。
domContentLoadedEventStart DOMContentLoaded 事件触发的时间。 此时,DOM 树已构建完成,且无需等待样式表、图片等外部资源加载完成。
domContentLoadedEventEnd DOMContentLoaded 事件处理完成的时间。
domComplete 页面所有资源(包括图片、iframe 等)加载完成的时间(即 document.readyState 变为 'complete')。
loadEventStart load 事件触发的时间。 此事件在 domComplete 之后触发,表示页面完全加载完成。
loadEventEnd load 事件处理完成的时间。 至此,页面加载全过程结束。

思考下:有了这些指标,可以用来干嘛?(其实就是用performanceAPI计算性能指标的原理所在,

Performance API 依赖浏览器内核提供的高精度时间戳,其核心原理是基于 单调时间(Monotonic Time) ,而非系统时间(Wall Clock Time)。

  • 单调时间的优势 :不受系统时间调整(如手动修改时间、NTP 同步)影响,确保时间间隔计算的准确性。例如,performance.now() 返回的是从浏览器启动到当前的毫秒数,精度可达微秒级(1ms = 1000μs)。
  • 底层实现 :浏览器通过操作系统接口(如 Linux 的 clock_gettime(CLOCK_MONOTONIC)、Windows 的 QueryPerformanceCounter)获取单调时间,并封装为 DOMHighResTimeStamp 类型。
- 页面加载阶段指标(基于 PerformanceTiming)

以下指标均通过 事件触发时间戳的差值 计算,按页面加载流程顺序说明:

指标名称 计算公式 原理说明
DNS 查询耗时 domainLookupEnd - domainLookupStart 浏览器在 fetchStart 后触发 DNS 查询,记录开始与结束时间戳。若使用缓存,两者相等(耗时为 0)。
TCP 连接耗时 connectEnd - connectStart 包含 TCP 三次握手(及 TLS 握手,若为 HTTPS)的时间。connectStart 为开始建立连接的时间,connectEnd 为连接成功的时间。
HTTP 请求响应耗时 responseEnd - requestStart 从浏览器发送请求(requestStart)到接收完响应数据(responseEnd)的时间,包含网络传输与服务器处理时间。
DOM 解析耗时 domInteractive - domLoading domLoading 表示 HTML 解析开始,domInteractive 表示 DOM 树构建完成,两者差值为解析 HTML 的耗时。
资源加载耗时 domComplete - domInteractive domInteractive 后,浏览器开始加载外部资源(如图片、脚本),domComplete 表示所有资源加载完成。
首屏时间(FP/FCP) 需结合 PerformancePaint API ,通常取 firstContentfulPaint 时间戳 传统 PerformanceTiming 无直接首屏指标,现代浏览器通过 PerformancePaint 记录首次绘制内容的时间(如文本、图片)。
完全加载时间 loadEventEnd - navigationStart 从导航开始到 load 事件处理完成的总耗时,包含所有资源加载与脚本执行时间。
- 用户交互性能指标(基于 PerformanceMark/Measure)

开发者可自定义标记点,通过 时间戳差值 计算特定流程的耗时:

  • 示例:按钮点击到响应的耗时
javascript 复制代码
// 标记点击开始
performance.mark('buttonClickStart');
// 按钮点击事件处理函数
button.addEventListener('click', () => {
  // 业务逻辑
  // 标记点击结束
  performance.mark('buttonClickEnd');
  // 计算耗时
  performance.measure('buttonResponseTime', 'buttonClickStart', 'buttonClickEnd');
  
  // 获取结果
  const measure = performance.getEntriesByName('buttonResponseTime')[0];
  console.log(`按钮响应耗时:${measure.duration}ms`);
});

原理 :通过 performance.mark() 记录自定义事件的时间戳,performance.measure() 计算两个标记点的时间差,底层依赖单调时间确保精度。

- 资源加载性能指标(基于 PerformanceResourceTiming)

通过 performance.getEntriesByType('resource') 获取单个资源的加载数据,核心指标计算:

  • 资源加载总耗时responseEnd - startTimestartTime 为资源开始请求的时间)。
  • 网络传输耗时responseEnd - requestStart(排除服务器处理时间)。
  • 缓存命中耗时 :若 fromCachetrue,则耗时极短(仅读取缓存的时间)。

光获取性能指标没啥用,要转化收益还是得针对性能问题去有针对性地优化

性能指标的应用场景与优化方向(略写如下)

  1. DNS耗时过长
    • 原因:域名未被缓存,或DNS服务器响应慢
    • 优化:使用DNS预解析(<link rel="dns-prefetch">),或选择更快的DNS服务(如Cloudflare DNS)
  2. TCP连接耗时过长
    • 原因:首次连接需三次握手,HTTPS还需TLS握手
    • 优化:启用HTTP/2(复用连接)、使用Keep-Alive保持长连接,或部署CDN减少物理距离
  3. DOM解析耗时过长
    • 原因:HTML文档过大,或包含阻塞渲染的脚本/样式表
    • 优化:拆分HTML、异步加载非关键脚本(async/defer)、使用CSS媒体查询(media="print"等)避免阻塞。
  4. 资源加载耗时过长
    • 原因:图片未压缩、脚本体积过大、CDN节点离用户太远
    • 优化:使用WebP图片、代码分割(import())、启用懒加载(loading="lazy")、切换CDN节点。

现代浏览器的性能监控优化

随着Web标准发展,除了PerformanceTiming,还新增了更精准的指标接口:

接口名称 用途
PerformancePaint API 记录首次渲染(FP)、首次内容渲染(FCP)、最大内容渲染(LCP)等首屏相关时间
PerformanceEntryTiming API 细化资源加载阶段(如responseStart到responseEnd可拆分为transferStart和transferEnd)
User Timing API 允许开发者自定义性能指标(如接口响应时间、动画流畅度等)

本文的篇幅有点太长了,侧重点在于扩展比较枯燥的知识面,更有意思的应用场景,以及性能指标的详解就没有铺开来写,后面计划会针对应用场景和性能指标详解各写一篇详细的🫠

相关推荐
天天打码2 分钟前
Sass具有超能力的CSS预处理器
前端·css·sass
Yana.nice9 分钟前
sysctl优先级顺序
服务器·前端·网络
米花丶12 分钟前
异步加载弹出层动画丢失问题
前端
小桥风满袖14 分钟前
Three.js-硬要自学系列31之专项学习动画混合
前端·css·three.js
Lanqing_076017 分钟前
淘宝商品详情图API接口返回参数说明
java·服务器·前端·api·电商
karshey27 分钟前
【Element Plus】Menu组件:url访问页面时高亮对应菜单栏
前端·javascript·vue.js
xiaogg367827 分钟前
系统网站首页三种常见布局vue+elementui
前端·vue.js·elementui
日升31 分钟前
AI 组件库-MateChat × 大模型:DeepSeek、OpenAI 和 阿里通义问 (Qwen)的全流程接入实战(三)
前端·ai编程·trae
Barcke32 分钟前
AI赋能开发者工具:智能提示词编写与项目管理实践
前端·后端