Skip to content

Commit ffb618d

Browse files
committed
docs: 📝 添加性能监控相关文档,包括 PerformanceObserver、性能指标、CDN 引入、白屏算法等
1 parent 125ce79 commit ffb618d

7 files changed

Lines changed: 285 additions & 1 deletion

File tree

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
本项目采用新一代性能监控API:`PerformanceObserver` ,它可以精准的记录一些性能指标,可以有效的帮助我们去针对性的优化项目。并且它是基于事件驱动的异步监测方式,不会阻塞主线程的执行。
2+
3+
我们直接切入主题,看看这个API可以监测哪些性能数据(带 `*` 是比较常用的性能指标的条目)
4+
5+
我们也可以通过 `PerformanceObserver.supportedEntryTypes` 来查看浏览器支持哪些性能条目,下面是我谷歌浏览器所输出的 `entryTypes`
6+
7+
![](https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/5aa8b7759f9f479da94498f2545a502e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgTmkwZHVhbm4=:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMzYzMTAyMzcwNjg2NTg5MiJ9&rk3s=e9ecf3d6&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1743864301&x-orig-sign=kSfEYxrDMQ%2Bfctu6OegNwS9LpPk%3D)
8+
9+
10+
11+
12+
![](https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/11fde7e7bc2b4aecb8057d79de9592bb~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgTmkwZHVhbm4=:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMzYzMTAyMzcwNjg2NTg5MiJ9&rk3s=e9ecf3d6&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1743864301&x-orig-sign=qFhjRKm6STRUY7rOYd7SvxvuyzE%3D)
13+
14+
15+
16+
17+
18+
19+
20+
## 为什么使用 PerformanceObserver
21+
22+
那么,为什么我们要选择PerformanceObserver呢?它的独特优势在于:
23+
24+
1. 实时性:PerformanceObserver能够实时捕获性能事件,让你在第一时间了解网页的性能表现。这对于及时发现并解决问题至关重要。
25+
1. 灵活性:通过配置PerformanceObserver的回调函数,你可以自定义处理性能数据的方式。无论是简单的日志记录,还是复杂的性能分析,都能轻松应对。
26+
1. 可扩展性:随着Web标准的不断发展,PerformanceObserver支持的性能条目也在不断增加。这意味着你可以用它来监控更多类型的性能数据,满足日益增长的性能优化需求。
27+
1. 易用性:虽然PerformanceObserver提供了强大的功能,但它的API设计相对简洁直观。即使是初学者,也能较快上手并应用到实际项目中。
28+
29+
# PerformanceObserver
30+
31+
## 基础示例
32+
33+
下面我将通过一个简单的例子来介绍PerformanceObserver的基础使用。这个例子将展示如何设置一个PerformanceObserver来监听页面上的resource性能条目,即资源加载事件。
34+
35+
```
36+
js
37+
代码解读
38+
复制代码
39+
// 创建一个 PerformanceObserver 实例 const performanceObserver = new PerformanceObserver((list) => { // 回调函数会在每次有匹配的 PerformanceEntry 被添加到 PerformanceTimeline 时被调用 for (const entry of list.getEntries()) { // 检查 entry 类型是否为我们关注的 'resource' if (entry.entryType === 'resource') { console.log(`Resource loaded: ${entry.name}`); console.log(`Duration: ${entry.duration} ms`); console.log(`Initiator Type: ${entry.initiatorType}`); // 哪个类型的事件触发了这个资源的加载 // 可以根据需要添加更多日志或处理逻辑 } } }); // 告诉 PerformanceObserver 我们想要监听哪些类型的 PerformanceEntry // 在这个例子中,我们监听 'resource' 类型的条目 performanceObserver.observe({ type: 'resource' });
40+
```
41+
42+
## 静态方法
43+
44+
通过上面的基础示例了解了 PerformanceObserver 的使用, 除了监听 resource 还可以监听其他的类型。你可以通过PerformanceObserver 的静态方法 supportedEntryTypes 查询当前浏览器支持哪些类型的性能条目(PerformanceEntry)。
45+
46+
```
47+
JS
48+
代码解读
49+
复制代码
50+
// 检查浏览器支持的 PerformanceEntry 类型 const supportedTypes = PerformanceObserver.supportedEntryTypes;
51+
```
52+
53+
![](https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/3ac0ea249ca440bb9724f8d36afea52c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgTmkwZHVhbm4=:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMzYzMTAyMzcwNjg2NTg5MiJ9&rk3s=e9ecf3d6&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1743864301&x-orig-sign=Ibg%2B6ouVCIoneUPOO4j45acqvLA%3D)
54+
55+
## 实例方法
56+
57+
- 创建实例
58+
- 通过实例 observe() 监听多个性能条目
59+
- 可以通过 disconnect() 取消监听性能条目
60+
61+
```
62+
js
63+
代码解读
64+
复制代码
65+
// 创建实例,当记录指定类型的性能条目出现时,性能监测对象的回调函数将会被调用。const observer = new PerformanceObserver(function (list, obj) { var entries = list.getEntries(); for (var i = 0; i < entries.length; i++) { // mark、element 的性能条目会在这里触发 }});// 监听指定性能条目,observer.observe({ type: 'mark' });// 可设置多个监听observer.observe({ type: 'element' });setTimeout(()=> { // 取消监听 observer.disconnect();}, 3000)
66+
```
67+
68+
### observer.observe()
69+
70+
针对 observe 方法需要详细再说明下。他支持多个参数
71+
72+
```
73+
JS
74+
代码解读
75+
复制代码
76+
observer.observe({ type: 'navigation', buffer: true})
77+
```
78+
79+
- type type 是一个字符串,用于指定您只关心的**一种**性能条目类型。例如,如果您只关心页面加载(navigation)的性能数据,就可以使用此选项。
80+
81+
- bufferd 是否缓存加载过的性能条目,这样在 observe 监控调用之前发生的性能条目也会触发回调。**必须与 type 选项**一起使用。
82+
83+
- entryTypes 一个字符串对象的数组,每个字符串指定一个要观察的性能条目类型。不能与 “type”、“buffered” 或 “durationThreshold” 选项一起使用。
84+
85+
- durationThreshold 当你使用 PerformanceObserver API 来观察浏览器的性能条目(performance entries)时,durationThreshold 是一个可选的配置项,它允许你设置一个阈值,以便只接收那些持续时间超过该阈值的条目。
86+
87+
- durationThreshold 的默认值是 104ms:这意味着,默认情况下,PerformanceObserver 只会向你报告那些持续时间超过 104 毫秒的性能条目。
88+
- 设置为 16ms 以获取更多交互:由于许多用户交互(如点击、滚动等)的响应时间通常远小于 104 毫秒,因此如果你对这类快速交互感兴趣,你可能需要将 durationThreshold 降低到 16 毫秒或更低。这样做可以让你捕获到更多的交互事件,并了解它们的性能特性。
89+
- 最小 durationThreshold 是 16ms:这是 API 的一个限制,你不能将 durationThreshold 设置为小于 16 毫秒的值。这是因为低于这个值的性能条目可能对于大多数应用来说并不重要,而且过于频繁地触发观察者可能会导致性能下降。
90+
91+
- 请注意,durationThreshold 主要与那些**具有持续时间**的性能条目相关,如 longtask、event 类型的条目。对于其他类型的条目(如 mark、measure 等),这个阈值可能不适用或具有不同的含义。
92+
93+
## PerformanceEntry
94+
95+
### 基本介绍
96+
97+
PerformanceEntry是一个通用接口,它定义了一系列属性,如name(性能条目的名称)、entryType(性能条目的类型)、startTime(开始时间戳)、duration(持续时间,如果适用)等,用于描述一个性能事件的各个方面。不同的性能事件(如资源加载、页面渲染等)会生成不同类型的**PerformanceEntry**对象,这些对象都是PerformanceEntry的子类,各自拥有一些特定的属性和方法。
98+
99+
PerformanceObserver会自动为你捕获PerformanceEntry,并在你指定的回调函数中将它们作为参数传递给你。
100+
101+
每当有匹配的性能事件发生时,PerformanceObserver就会调用你的回调函数,并将一个包含新性能条目的PerformanceObserverEntryList对象作为参数传递给你。你可以通过遍历 **PerformanceObserverEntryList.getEntries()** 来访问每个PerformanceEntry对象。
102+
103+
```
104+
const p = new PerformanceObserver(list => { // PerformanceObserverEntryList 对象 const entries = list.getEntries() for(let entry of entries) { console.log('entry:', entry) }})p.observe({ type: 'navigation', buffered: true})
105+
```
106+
107+
一旦你获得了PerformanceEntry对象,你就可以利用它提供的属性和方法来分析和优化你的网页性能了。
108+
109+
110+
111+
112+
## 参考资料
113+
114+
[深入使用 PerformanceObserver 提到性能监控,你可能会想到performance API,但今天,我想 - 掘金](https://juejin.cn/post/7389164547029024809)

docs/使用文档/性能监控/aa.md

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
## FP (First Paint)
2+
3+
- First Paint(首次绘制)标志着浏览器开始在屏幕上渲染任何内容,包括背景颜色改变。
4+
- 这是用户看到页面开始加载的第一个视觉反馈。尽管FP是一个相对宽泛的指标,但它能快速给出页面开始加载的初步指示。
5+
6+
7+
8+
9+
## FCP(First Contentful Paint):
10+
11+
FCP 是指从用户开始请求页面(即导航开始)到页面上第一个内容元素(例如文本、图像或 SVG 元素)被绘制到屏幕上所需的时间。它衡量的是页面响应速度,尤其是在用户等待页面呈现时,浏览器为其展示第一部分内容的时间。
12+
13+
有意义的内容包括:
14+
15+
- 页面中的文本
16+
- 图片
17+
- SVG 元素
18+
- Canvas 内容等
19+
20+
![](https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/7ef9f550a1624422ba0d628471a9476d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgTmkwZHVhbm4=:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMzYzMTAyMzcwNjg2NTg5MiJ9&rk3s=e9ecf3d6&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1743868724&x-orig-sign=W%2B7Bsdnj3gZ3FqrZy7FdQOGCowE%3D)
21+
22+
在上图中所示的加载时间轴中,FCP 发生在第二帧,因为这是第一个文本和图片元素渲染到屏幕上的时间。
23+
24+
您会发现,虽然部分内容已呈现,但并非所有内容都已呈现。这是一个重要的区别,需要在 First Contentful Paint 和 Largest Contentful Paint (LCP) 之间加以区分,后者旨在衡量网页的主要内容何时加载完毕。
25+
26+
为了提供良好的用户体验,网站应尽量将首次有意义的绘制时间控制在 1.8 秒或更短的时间。为确保大多数用户都能达到此目标值,一个合适的衡量阈值是网页加载时间的第 75 个百分位数,并按移动设备和桌面设备进行细分。
27+
28+
![](https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/0e89ea08bd1a466c85de3eb25aa4b1af~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgTmkwZHVhbm4=:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMzYzMTAyMzcwNjg2NTg5MiJ9&rk3s=e9ecf3d6&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1743868724&x-orig-sign=Hq%2F5OzLDmCwKlFF2OM7qR7j9i%2B8%3D)
29+
30+
#### **衡量 FCP 的方案**
31+
32+
衡量 FCP 的方案有多种不同的方式,接下来我们将一一介绍。
33+
34+
35+
36+
37+
[PageSpeed Insights ](https://pagespeed.web.dev/?hl=zh-cn)(简称 PSI)是由 Google 提供的一个免费的在线工具,用于分析网页的加载性能并提供优化建议。它主要通过评估页面的加载速度和响应能力,帮助开发者和站点所有者提升网页的用户体验。PageSpeed Insights 通过多项性能指标和数据,帮助用户理解页面的加载过程,并提供改进建议以优化网页的性能。
38+
39+
![](https://p0-xtjj-private.juejin.cn/tos-cn-i-73owjymdk6/c625b89b2eea451fa5c351b8e58c094d~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAgTmkwZHVhbm4=:q75.awebp?policy=eyJ2bSI6MywidWlkIjoiMzYzMTAyMzcwNjg2NTg5MiJ9&rk3s=e9ecf3d6&x-orig-authkey=f32326d3454f2ac7e96d3d06cdbb035152127018&x-orig-expires=1743868724&x-orig-sign=D0hCvVW5NB3K05d4hjQuZzKQqA4%3D)
40+
41+
42+
43+
44+
#### **如何提高 FCP**
45+
46+
如需了解如何提高特定网站的 FCP,您可以运行 Lighthouse 性能审核,并留意审核中建议的任何具体优化建议或诊断结果。
47+
48+
如需了解如何普遍提高 FCP(适用于任何网站),请参阅以下效果指南:
49+
50+
- [移除阻塞渲染的资源 ](https://developer.chrome.com/docs/lighthouse/performance/render-blocking-resources?hl=zh-cn)
51+
- [缩减 CSS 大小 ](https://developer.chrome.com/docs/lighthouse/performance/unminified-css?hl=zh-cn)
52+
- [移除未使用的 CSS ](https://developer.chrome.com/docs/lighthouse/performance/unused-css-rules?hl=zh-cn)
53+
- [移除未使用的 JavaScript ](https://developer.chrome.com/docs/lighthouse/performance/unused-javascript?hl=zh-cn)
54+
- [预先连接到必需的资源 ](https://developer.chrome.com/docs/lighthouse/performance/uses-rel-preconnect?hl=zh-cn)
55+
- [缩短服务器响应时间(TTFB) ](https://developer.chrome.com/docs/lighthouse/performance/server-response-time?hl=zh-cn)
56+
- [避免多次网页重定向 ](https://developer.chrome.com/docs/lighthouse/performance/redirects?hl=zh-cn)
57+
- [预加载关键请求 ](https://developer.chrome.com/docs/lighthouse/performance/uses-rel-preload?hl=zh-cn)
58+
- [避免网络加载过大 ](https://developer.chrome.com/docs/lighthouse/performance/total-byte-weight?hl=zh-cn)
59+
- [使用高效的缓存策略提供静态资源 ](https://developer.chrome.com/docs/lighthouse/performance/uses-long-cache-ttl?hl=zh-cn)
60+
- [避免 DOM 构建过大 ](https://developer.chrome.com/docs/lighthouse/performance/dom-size?hl=zh-cn)
61+
- [最大限度地缩短关键请求深度 ](https://developer.chrome.com/docs/lighthouse/performance/critical-request-chains?hl=zh-cn)
62+
- [确保文本在页面字体加载时保持可见状态 ](https://developer.chrome.com/docs/lighthouse/performance/font-display?hl=zh-cn)
63+
- [请将较低的请求数量和较小的输入大小 ](https://developer.chrome.com/docs/lighthouse/performance/resource-summary?hl=zh-cn)
64+
65+
## LCP (Largest Contentful Paint)
66+
67+
- Largest Contentful Paint(最大内容绘制)衡量的是页面上最大的可见元素(文字块或图像)变为可见所需的时间。
68+
- 这是用户感知页面加载完成的重要标志,直接影响到用户感受到的速度。LCP应该尽快发生,理想情况下在2.5秒内。
69+
70+
71+
72+
73+
74+
75+
76+
77+
## **参考资料**
78+
79+
[面试导航](https://www.codecrack.cn/zh/performance/FCP)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
## 使用 CDN
2+
3+
你还可以通过CDN获取构建好的文件。将以下代码添加到 HTML 文件的 `<script>` 标签中:
4+
5+
```
6+
<script src="https://cdn.jsdelivr.net/npm/@ni0duann/monitor-sdk@1.0.1/dist/index.min.js"></script>
7+
```
8+
9+
## 使用 script 标签引入
10+
11+
通过直接在 HTML 文件中添加 `<script>` 标签,引入构建好的文件:
12+
13+
```
14+
<!DOCTYPE html>
15+
<html>
16+
<head>
17+
<meta charset="utf-8" />
18+
<!-- 引入文件 -->
19+
<script src="https://cdn.jsdelivr.net/npm/@ni0duann/monitor-sdk@1.0.1/dist/index.min.js"></script>
20+
</head>
21+
</html>
22+
```
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
## 概述
2+
3+
白屏检测算法用于检测网页是否处于白屏状态,通过在页面视口选取多个检测点,判断这些点对应的元素是否为空或不可见,进而计算空白点占比,与预设阈值比较来确定是否为白屏。此外,算法还支持在页面路由变化时重新检测,并在检测到白屏时提供可视化反馈和向服务器发送白屏计数请求。
4+
5+
## 算法流程
6+
7+
1. 初始化参数
8+
9+
- 阈值(`threshold`):判断为白屏的空白点占比阈值,默认值为 0.8(即 80%)。
10+
- 延迟时间(`delay`):延迟检测的时间,默认值为 3000 毫秒。
11+
12+
1. 检测点选取
13+
14+
- 获取当前视口的宽度(`viewportWidth`)和高度(`viewportHeight`)。
15+
- 若视口宽度或高度为 0,则直接判定为白屏。
16+
- 选取视口的中心点以及四个角落作为检测点,具体坐标如下:
17+
- 中心点:`[viewportWidth / 2, viewportHeight / 2]`
18+
- 左上角:`[0, 0]`
19+
- 右上角:`[viewportWidth - 1, 0]`
20+
- 左下角:`[0, viewportHeight - 1]`
21+
- 右下角:`[viewportWidth - 1, viewportHeight - 1]`
22+
23+
1. 检测点判断
24+
25+
- 遍历每个检测点,获取该点坐标下的所有元素(按从顶层到底层顺序)。
26+
- 从这些元素中选取最顶层非 `body``html` 的可见元素。若未找到有效元素,则认为该点为空白点。
27+
- 对于找到的有效元素,判断其是否为空内容元素,若是则认为该点为空白点。判断元素是否为空内容元素的规则如下:
28+
- 检查元素的文本内容,若不为空则不为空内容元素。
29+
- 检查元素是否包含图片(`<img>` 标签),若包含则不为空内容元素。
30+
- 检查元素是否包含 `Canvas``SVG` 元素,若包含则不为空内容元素。
31+
- 检查元素是否包含输入元素(如 `<input>``<textarea>``<select>`),若包含则不为空内容元素。
32+
- 递归检查元素的子元素(两层),若有可见子元素则不为空内容元素。
33+
34+
1. 计算空白点比例
35+
36+
统计空白点的数量,计算空白点占总检测点数量的比例(`blankRatio`)。
37+
38+
1. 判断是否为白屏
39+
40+
将计算得到的空白点比例与预设阈值进行比较,若 `blankRatio >= threshold`,则判定为白屏;否则判定为非白屏。
41+
42+
1. 可视化反馈与服务器交互
43+
44+
- 若检测到白屏,在控制台输出错误信息,弹出警告框,并向服务器发送请求增加白屏计数。
45+
- 若未检测到白屏,在控制台输出页面渲染正常的信息。
46+
47+
1. 路由变化检测
48+
49+
监听页面的路由变化事件(`pushState``replaceState``popstate`),在路由变化时重新进行白屏检测,并根据检测结果提供相应的可视化反馈
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
性能监控由于打开网站,一般情况几秒就能获得数据,故采用延时上报方式:
2+
3+
```JavaScript
4+
reportData({
5+
url: this.options.reportUrl,
6+
data: reportPayload, // 包含性能数据+其他数据
7+
delay: 0 // 立即发送(外层已有setTimeout)
8+
});
9+
}, this.options.delay);
10+
```

docs/贡献文档/index.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## 如何联系我们:
2+
3+
[EzStars团队](https://ezstars.github.io/EzMonitor/about.html)
4+
5+
## PR提交规范
6+
7+
```Plain
8+
pnpm run commit
9+
```
10+
11+
![img](https://dcna63fdf6da.feishu.cn/space/api/box/stream/download/asynccode/?code=M2IxZDU3NDI5NDMxZjAwYTU2NjFkMWU2ZjEwYzNlZTFfMmw2YmtrODQ1d3BxdFFZNk91TEtrbkgyQ01mMzdBSHdfVG9rZW46VXp5c2JSU1Rsb3pXMnh4cEI3S2N3a1NhbjZiXzE3NDM3ODI1Mjg6MTc0Mzc4NjEyOF9WNA)

0 commit comments

Comments
 (0)