npm package: @fe-hl/monitor-sdk
Description: 前端监控SDK
Author: hulei
Latest version: 1.3.2

# 前端监控 SDK

## 安装

```npm
npm i @fe-hl/monitor-sdk -S
```

## 参数说明

| 参数                         | 是否必传 | 默认值 |               说明               |
| :--------------------------- | :------: | :----: | :------------------------------: |
| pId                          |   true   |   -    |             产品 ID              |
| reportUrl                    |   true   |   -    |           上报接口地址           |
| reportInterval               |  false   |   10   |        上报间隔`默认10秒`        |
| batchSize                    |  false   |   20   |   每次上报的最大条数`默认20条`   |
| debug                        |  false   | false  | debug 模式打印控制台，不上报接口 |
| jsErrorLog                   |  false   | false  |             js 异常              |
| promiseErrorLog              |  false   | false  |           promise 异常           |
| resourcesErrorLog            |  false   | false  |           资源加载异常           |
| exposureLog                  |  false   | false  |             曝光埋点             |
| automaticBurialPointLog      |  false   | false  |             自动埋点             |
| pageDwellTimeLog             |  false   | false  |           页面停留时间           |
| pvLog                        |  false   | false  |                pv                |
| xhrLog                       |  false   | false  |             接口监控             |
| resourcesPerfLog             |  false   | false  |           资源加载性能           |
| perfLog                      |  false   | false  |           页面渲染性能           |
| longTaskLog                  |  false   | false  |              长任务              |
| behaviorRecorderLog`(1.3.0)` |  false   | false  |           用户行为录制           |
| sampleRate                   |  false   |  如下  |           抽样上报比例           |

## sampleRate 抽样上报比例

- 默认值：`0.5`，即上报 50%，`1` 即上报 100%

| 参数                 | 默认值 |     说明     |
| :------------------- | :----: | :----------: |
| exposure             |   1    |   曝光埋点   |
| automaticBurialPoint |   1    |   自动埋点   |
| pageDwellTime        |   1    | 页面停留时间 |
| pv                   |   1    |      pv      |
| behaviorRecorder     |   1    | 用户行为录制 |
| xhr                  |  0.5   |   接口监控   |
| resourcesPerf        |  0.5   | 资源加载性能 |
| perf                 |  0.5   | 页面渲染性能 |

## 使用

```js
import MonitorSdk from '@fe-hl/monitor-sdk';

const monitorSdk = MonitorSdk({
	pId: '1000', // 产品ID
	reportUrl: 'http://127.0.0.1:9001/report', // 上报的地址
	debug: false, // 是否开启debug，开启后打印控制台不上报
	jsErrorLog: true, // js异常
	promiseErrorLog: true, // promise异常
	resourcesErrorLog: true, // 资源加载异常
	exposureLog: true, //  // 曝光
	automaticBurialPointLog: true, // 自动埋点
	pageDwellTimeLog: true, // 页面停留时间
	pvLog: true, // PV
	xhrLog: true, // 接口监控
	resourcesPerfLog: true, // 资源加载性能
	perfLog: true, // 页面渲染性能
	longTaskLog: true, // 长任务
	behaviorRecorderLog: true, // 用户行为录制
});
```

## 手动上报

```js
import { monitorSdk } from '@fe-hl/monitor-sdk';

// 自定义上报
monitorSdk.report({
	type: 'click', // 类型必填
	message: '下单成功',
});
```

## 爆光埋点

- 给需要`爆光`的元素加上`data-exposure`属性，当元素在可视区域内，上报接口

```html
<div data-exposure="广告1">广告</div>
<div data-exposure="{id:100}">广告</div>
```

### 动态节点手动绑定监听

- **forceObservers**:当动态生成的节点需要监听曝光时，需要手动绑定监听
- 目前已经通过`MutationObserver`实现动态节点智能监听，无需手动绑定

```js
import { monitorSdk } from '@fe-hl/monitor-sdk';

monitorSdk.forceObservers();
```

## 无痕埋点

- 当元素发生点击事件，如果元素有`data-track`属性会自动上报接口

```html
<el-button type="primary" size="default" data-track="{userId:'1000'}">
	无痕埋点
</el-button>

<el-button type="primary" size="default" data-track="report1">
	无痕埋点
</el-button>
```

## 用户行为录制

- **behaviorRecorder**:开启用户行为录制
- 对用户界面操作流程进行录制，并生成行为日志，用于后续分析用户行为

```js
import { monitorSdk } from '@fe-hl/monitor-sdk';

monitorSdk.behaviorRecorder.start(); // 开始录制
monitorSdk.behaviorRecorder.stop(); // 停止录制并且上报
```

### 行为录制回放

```js
import rrwebPlayer from 'rrweb-player';
import 'rrweb-player/dist/style.css';
let replayer = new rrwebPlayer({
	target: document.getElementById('player'), // 回放容器(建议的尺寸1060*760)
	props: {
		events, // 上报的数据
	},
});
```

## 性能关键指标优化说明

| 指标        | 计算方式                                                | 说明                                                                                                                           |
| ----------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| TTFB        | 通过 `web-vitals` 库测量                                | **首字节时间**：从页面重定向开始到接收服务器返回的第一个字节的时间差                                                           |
| FP          | 通过`PerformanceObserver` 测量                          | **首次绘制时间&白屏时间**：浏览器将第一个像素（通常是背景色）绘制到屏幕的时间，反映白屏阶段时长                                |
| FCP         | 通过 `web-vitals` 库测量                                | **首次内容绘制**：浏览器首次渲染出 DOM 内容的时间（如文本、图像等）                                                            |
| FMP(被废弃) | 通过 `web-vitals` 库测量                                | **首次有意义绘制**：主要内容完成渲染的时间点（主观指标，通常对应核心内容可见或可交互时刻）                                     |
| LCP         | 通过 `web-vitals` 库测量                                | **最大内容渲染**：视窗内最大内容元素（如图片/标题块）完成渲染的时间（动态指标，随加载过程更新）                                |
| DCL         | `domContentLoadedEventEnd - domContentLoadedEventStart` | **DOM 解析耗时**：DOMContentLoaded 事件从开始到结束的持续时间（反映 DOM 树构建速度）                                           |
| L           | `loadEventStart - fetchStart`                           | **页面完全加载时间**：从开始加载到 load 事件触发的时间（包含所有资源加载）                                                     |
| TTI(被废弃) | 通过 `web-vitals` 库测量                                | **首次可交互时间**：页面达到完全可交互状态的时间（需满足 FP 完成+主线程空闲+元素可操作）                                       |
| FID(被废弃) | 通过 `web-vitals` 库测量                                | **首次输入延迟**：用户首次交互操作（点击/输入）到浏览器实际响应的延迟时间                                                      |
| INP(新标准) | 通过 `web-vitals` 库测量                                | **交互到下一次绘制**：INP 记录了从用户与页面交互（如点击、触摸或按键）开始，到浏览器真正将交互结果绘制到屏幕上为止所经过的时间 |

### TTI 触发条件详解

1. **首次绘制完成**：页面已完成至少一个像素的渲染（FP 阶段结束）
2. **主线程空闲**：浏览器主线程连续空闲时间 ≥ 50ms（无长任务阻塞）
3. **元素可操作**：关键交互元素（按钮/输入框等）可即时响应用户操作  
   → 当三项条件同时满足时，TTI 被记录

### FID 测量原理

1. **用户首次交互**：监测页面生命周期中的第一次用户操作（点击/触摸/键盘输入）
2. **主线程阻塞检测**：若交互发生时主线程正执行长任务（JS 执行/渲染等），记录任务结束到响应开始的延迟
3. **阈值判定**：实际延迟 = 浏览器开始处理输入事件的时间戳 - 用户交互时间戳

### INP

- INP 记录的是用户与页面进行交互（如点击、点击、键盘输入）到下一次绘制（浏览器将更新后的像素绘制到屏幕上）所经过的延迟时间。它衡量的是“用户操作后，页面更新的快慢”。

## 指标参考

| 指标     | 优          | 中 (需要改进) | 差        | 说明与解读                                                                                                                                                        |
| :------- | :---------- | :------------ | :-------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **TTFB** | 0 - 800 ms  | 800 - 1800 ms | > 1800 ms | **第一字节时间**<br>衡量服务器响应速度。从请求发出到收到响应第一个字节的时间。反映了服务器处理能力和网络链路质量。                                                |
| **FP**   | 0 - 1.0 sec | 1.0 - 2.5 sec | > 2.5 sec | **首次绘制**<br>页面发生**第一次任何形式**的像素绘制（背景色、边框等）的时间点。标志着用户感知“有东西在加载”。                                                    |
| **FCP**  | 0 - 1.8 sec | 1.8 - 3.0 sec | > 3.0 sec | **首次内容绘制**<br>页面发生**第一次任何内容**（文本、图片、SVG 等）绘制的时间点。是用户感知加载的关键指标。                                                      |
| **LCP**  | 0 - 2.5 sec | 2.5 - 4.0 sec | > 4.0 sec | **最大内容绘制**<br>**核心 Web 指标**之一。视口内最大内容元素（如图片、标题文本块）渲染完成的时间。衡量**加载体验**的感知速度。                                   |
| **FID**  | 0 - 100 ms  | 100 - 300 ms  | > 300 ms  | **首次输入延迟**<br>**（已被 INP 取代）** 衡量用户**第一次**与页面交互（点击、 tap 等）到浏览器**开始处理**事件之间的延迟。主要反映主线程的繁忙程度。             |
| **INP**  | 0 - 200 ms  | 200 - 500 ms  | > 500 ms  | **下一次绘制的交互**<br>**核心 Web 指标**之一（取代 FID）。测量页面整个生命周期内，所有用户交互的**最长**延迟（输入延迟+处理时间+呈现延迟）。衡量**交互响应性**。 |
| **CLS**  | 0 - 0.1     | 0.1 - 0.25    | > 0.25    | **累积布局偏移**<br>**核心 Web 指标**之一。衡量页面在整个生命周期中发生的**意外布局偏移**的总分数。衡量**视觉稳定性**。分数越低越好。                             |
| **TBT**  | 0 - 200 ms  | 200 - 600 ms  | > 600 ms  | **总阻塞时间**<br>介于 FCP 和 TTI 之间，主线程被**长任务**（执行时间 > 50ms 的任务）阻塞的总时间。是衡量**交互准备度**的优秀实验室指标。                          |
| **TTI**  | 0 - 3.8 sec | 3.8 - 7.3 sec | > 7.3 sec | **可交互时间**<br>页面已显示有用内容，并且能够可靠地响应用户输入的时间点。要求主线程有足够长的空闲时间（无长任务）。                                              |