前端数据埋点(6):web-vitals——三个数怎么算出来
上一篇框架钩子——Vue 接住的错window.onerror 听不到下一篇Web Vitals——页面慢不慢不是再包一层 fetch相关一次点击如何变成一条埋点 · 上报系列前端数据埋点· 第 6 篇前五篇是错误、点击、路由、信封。本篇加餐从库讲起页面体感慢不慢听的是 Performance 时间线不是再包一层fetch。web-vitals 把时间线收成 LCP / INP / CLS。讲机制不是把官方 README 抄一遍。源码按 v5.1.0。何时装信封、切标签和后退缓存下一篇再写。先说结论结算页能打开按钮也能点用户仍可能觉得卡。这不是TypeError也不是pay_click点了几次是三个数指标人的体感单位LCP最大那块内容何时画完首屏主图、大标题毫秒INP点下去到画面有反馈最差的那一次毫秒CLS排版跳了多少按钮突然被顶下去无量纲分数自己new PerformanceObserver去听largest-contentful-paint很容易漏预渲染要从激活时刻起算、页已经 hidden 之后的绘制不要记、用户一点击 LCP 就该停。INP、CLS 各自还有另一堆规则。web-vitals收进三个函数。你只负责订阅。三个回调拿到的都是Metric顶层字段一样「是哪个节点」在entries里没有metric.element。import{onLCP,onINP,onCLS}fromweb-vitalsonLCP((metric){constentrymetric.entries[metric.entries.length-1]// metric.name LCP// metric.value 毫秒比如 2400// metric.rating good | needs-improvement | poor// metric.id 这一页这次 LCP 的实例// metric.navigationType navigate | reload | back-forward-cache …// entry.element 最大那块 DOM跨域图可能是 null// entry.url 图的地址如果是图// entry.size 面积// entry.id 元素自己的 id 属性可能没有})onINP((metric){constentrymetric.entries.find((e)e.durationmetric.value)||metric.entries[0]// metric.name INP// metric.value 毫秒最差或接近最差那次交互// metric.rating// entry.name click | keydown | pointerdown …// entry.duration 这次从输入到下一帧的延迟// entry.target 点到的节点可能拿不到})onCLS((metric){constentrymetric.entries[metric.entries.length-1]// metric.name CLS// metric.value 分数最大那一段窗口的累加// metric.rating// entry.value 这一跳自己的分数// entry.hadRecentInput true 表示刚输入完库计算时通常不计// entry.sources 哪些节点在动source.node 是 DOM})库做两件事用带buffered的PerformanceObserver收原料晚加载也能拿到已经发生的条目按 Chrome 同一套规则收成一个Metric。回调里已经是数不是要你自己从 entry 列表加总。delta是相对上次回调涨了多少上报终值看value。一句话web-vitals 负责把时间线收成三个数回调到了还不等于该发 HTTP。没有PerformanceObserver就静静返回不要补Date.now()假数。Chrome 的「好」大概是 LCP ≤ 2.5s、INP ≤ 200ms、CLS ≤ 0.1库会带上rating。1. 包装 API 听不到「画完了」第 2 篇能听到请求结束、脚本报错。首屏最大那张图何时画完不在XMLHttpRequest上。浏览器提供PerformanceObserver可以订阅largest-contentful-paint、layout-shift、交互用的event。web-vitals在这些条目上算出三个数。第 7 篇里的 SDK订的也是这三个函数。无埋点 XHRweb-vitals听谁被包装的open/sendPerformanceObserver、onLCP这类回调何时有数一次请求结束就定了页还开着数还能变你拿到的一次请求的字段已经收好的Metric2. 概念词典词是什么解决什么web-vitalsGoogle 的小库对外主要是onLCP/onINP/onCLS自己拼观察者时容易和 Chrome 的算法对不齐Metric回调里那份对象name、value、rating、id、entries、navigationType不用自己对阈值也不用自己翻是哪条 entryrating对照库内门槛good/needs-improvement/poorLCP 2500/4000INP 200/500CLS 0.1/0.25reportAllChanges值一变就回调默认关默认只在终值附近喊你一次buffered观察者能拿到订阅之前已经发生的条目脚本晚加载也不丢首屏 LCPINP 替代了旧的 FID第一次点击延迟。现在看整页交互里偏差的那一次不是第一次。新代码不要再订onFID。3. 怎么接到页面上npm 安装web-vitals和普通依赖一样import。不必抢在首屏脚本之前buffered能补到订阅前的条目。官方也建议把它放在业务代码之后。回调参数就是Metric。三个指标顶层字段相同字段含义nameLCP/INP/CLSvalue当前值。LCP、INP 是毫秒CLS 是分数rating对照上面的门槛id这一页这次指标的实例。从后退缓存恢复后会换新的entries算出这个值时用到的性能条目navigationType这次浏览怎么来的。解冻时是back-forward-cachedelta相对上次回调涨了多少。上报终值看valueentries里才是浏览器的原始条目三个指标不一样最后一条或对上value的那条上取什么用来干什么LCPelement、url、size知道该压哪张图路径用第 3 篇的htmlTreeAsString(entry.element)INPname事件类型、duration、target知道是点击还是按键、点了谁CLSsources[].node、hadRecentInput知道谁在跳LCP 的entries一般就一条就是当前最大的那块。INP 可能有多条用duration metric.value对上最差那次。跨域图、节点已经卸掉时element/target可能是null只剩url或什么都没有。埋点先留下这些就够name、value、rating、路由 name、DOM 路径。navigationType back-forward-cache的那次下一篇会丢掉。attribution 构建会多带摊平后的元素、交互信息大约多 1.5K。要查根因再换web-vitals/attribution。4. LCP最大块画完的时刻onLCP观察largest-contentful-paint。每来一条更大的内容就用它的startTime更新metric.value。页如果是预渲染的会减去激活时刻避免把用户没看见的那段算进去。页在用户看见之前就已经 hidden后台打开这条绘制不记。实现上是entry.startTime和firstHiddenTime比。LCP 不是一直听到关页。用户第一次真正的点击、按键或者页变成 hidden库会停观察、再回调一次终值。滚动也会让浏览器停发 LCP但程序触发的滚动不可靠库不拿滚动当停表信号。默认不设reportAllChanges时你往往只在停表附近收到一次。标题 800ms、大图 2.4s 那些中间值要自己开reportAllChanges: true才能在回调里看见。门槛写在库里[2500, 4000]。5. INP整页交互里偏差的那一次onINP观察 Event Timing 的event条目。浏览器不支持interactionId就直接返回没有数。一次交互的延迟是输入到下一帧绘制。库把各次交互收起来更新metric.value。交互很少时这个值就是最慢的那次交互很多时会取一个接近最差的代表值避免单次极端拖死整页。这和「支付按钮点击量」仍不是一回事。观察默认带durationThreshold: 40短于约 40ms 的交互不进这条观察。太短的第一次输入会再听first-input兜底以免整页零交互可报。页变成 hidden 时库把观察者里还没吐完的条目收完再强制回调一次。所以 INP 的终值通常也是离开或切走时才到你手上。门槛[200, 500]。6. CLS一段时间内位移的累加onCLS观察layout-shift。不是页面生命周期里所有位移加总而是按会话窗口收中间空档够长就另开一段value取最大的那段。刚输入完的位移hadRecentInput不计点开折叠面板不该算抖动。库会先等到 FCP 有了再报 CLS和 Chrome 自己的统计对齐。页 hidden 时同样收完剩余条目再回调一次。门槛[0.1, 0.25]。FCP 是第一次画出任意内容LCP 才是主内容。7. 回调到了还不等于该 POST三个函数的默认策略都偏向页还开着就继续改内部的Metric进后台或 LCP 停表时再喊你。开了reportAllChanges: true中间每一次变大都会进回调。不要在onLCP里直接track(EVENT)。同一页会留下一串越来越大的值服务端再聚合也分不清这一页到底有多慢。做法和第 1 篇的DURATION一样先放内存离开时发一次。这一段的完整口径在第 7 篇。bfcache 解冻时库会再给一套新id、navigationType back-forward-cache的数依据是pageshow的event.persisted。那套数往往偏快不要和第一次打开混在一起。第 7 篇写 SDK 为什么丢掉。v6 还在实验软导航SPA 里换页再测一套 LCP。本篇按硬加载讲。软导航是文档没换、路由换了和整页重载不是一回事。和前作怎么接篇补哪一段2无埋点包装fetch听不到「画完了」3行为栈entries里的节点仍用 DOM 路径1管线终值将走DURATION不是EVENT下一篇何时发信封、切标签不是后退缓存你可以从这里带走什么装web-vitals订onLCP/onINP/onCLS。脚本不必抢首屏观察者开了buffered。回调里是已经算好的Metric。看value和rating。LCP 最大元素在metric.entries里没有metric.element。LCP 听到更大的块就更新第一次点击或 hidden 时停INP 看交互延迟hidden 时出终值CLS 取最大的一段位移窗口。reportAllChanges只加密回调。何时track下一篇。没有 Performance API 就不要发假数。pay_duration用performance.measure不要冒充 LCP。仓库与相关文档GitHubweb-vitalssrc/onLCP.ts、src/onINP.ts、src/onCLS.ts本文按 v5.1.0指标定义web.dev/articles/vitals相关前作5框架钩子 · 4上报欢迎 Star、Issue 和 PR。本文是「前端数据埋点」第 6 篇web-vitals 如何把时间线收成三个数。不展开何时发信封、attribution 构建和软导航。

相关新闻

快速质量图导向法:从原理到代码,高效解决相位解包裹

快速质量图导向法:从原理到代码,高效解决相位解包裹

简介:本资源面向光学测量、数字全息与三维形貌重建领域的科研人员及高年级本科生,聚焦条纹投影与全息干涉中关键的相位解包裹难题,提供一套基于快速质量图导向策略的完整MATLAB实现方案。资源共6个文件(3个MATLAB数据文件.mat用于…

2026/10/26 12:12:42 阅读更多 →
基于机器学习的微博恶意用户识别系统设计与实践

基于机器学习的微博恶意用户识别系统设计与实践

简介:这是一套基于机器学习的微博恶意用户识别系统完整实现,面向计算机、人工智能、通信工程等专业的在校学生、教师及初级开发者,解决社交平台中异常账号检测与风险用户建模的实际问题,适用于课程设计、毕业设计、项目立项演示及…

2026/11/6 11:51:12 阅读更多 →
Hadoop+Spark金融信贷风控系统:从数仓分层到信用评分卡实践

Hadoop+Spark金融信贷风控系统:从数仓分层到信用评分卡实践

简介:本资源是一套完整的基于Hadoop与Spark的金融信贷风控大数据系统毕业设计源码,面向计算机、大数据、金融科技等相关专业本科生及初阶学习者,旨在解决海量信贷数据实时分析与风险建模的工程实践问题。压缩包共69个文件,含36个J…

2026/11/7 3:21:33 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/13 5:13:25 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/13 5:13:25 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/13 5:13:25 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/13 22:08:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/12 18:22:25 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/13 5:13:25 阅读更多 →

日新闻

周新闻

月新闻