monitor-track 1.10.2 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +15 -5
- package/cjs/config/index.d.ts +0 -4
- package/cjs/constant.d.ts +2 -2
- package/cjs/handlers/pv.d.ts +1 -0
- package/cjs/index.d.ts +4 -0
- package/cjs/index.js +1103 -1078
- package/cjs/reporter.d.ts +18 -7
- package/cjs/types/global.d.ts +16 -2
- package/cjs/types/index.d.ts +10 -5
- package/esm/config/global.js +17 -11
- package/esm/config/index.d.ts +0 -4
- package/esm/config/index.js +0 -4
- package/esm/constant.d.ts +2 -2
- package/esm/constant.js +3 -3
- package/esm/handlers/error.js +3 -8
- package/esm/handlers/pv.d.ts +1 -0
- package/esm/handlers/pv.js +19 -8
- package/esm/handlers/user-activity.js +2 -7
- package/esm/index.d.ts +4 -0
- package/esm/index.js +21 -5
- package/esm/package.json.js +1 -1
- package/esm/reporter.d.ts +18 -7
- package/esm/reporter.js +20 -10
- package/esm/types/global.d.ts +16 -2
- package/esm/types/index.d.ts +10 -5
- package/esm/utils/index.js +12 -16
- package/index.js +1454 -1422
- package/package.json +1 -1
package/cjs/reporter.d.ts
CHANGED
|
@@ -48,11 +48,13 @@ export declare const reportMap: {
|
|
|
48
48
|
/** 操作系统版本 */
|
|
49
49
|
osVersion: string;
|
|
50
50
|
pv: {
|
|
51
|
-
/** 子类型 */
|
|
52
|
-
subType: string;
|
|
53
51
|
/** 停留时间 */
|
|
54
52
|
stayTime: string;
|
|
55
53
|
};
|
|
54
|
+
lag: {
|
|
55
|
+
/** 页面卡顿时间 */
|
|
56
|
+
lagTime: string;
|
|
57
|
+
};
|
|
56
58
|
error: {
|
|
57
59
|
/** 子类型 */
|
|
58
60
|
subType: string;
|
|
@@ -125,13 +127,16 @@ export declare const reportMap: {
|
|
|
125
127
|
domContentLoadedEventEnd: string;
|
|
126
128
|
/** 是一个无符号long long 型的毫秒数,返回当解析器发送DOMContentLoaded (en-US) 事件,即所有需要被执行的脚本已经被解析时的Unix毫秒时间戳。 */
|
|
127
129
|
domContentLoadedEventStart: string;
|
|
128
|
-
/** 是一个无符号long long 型的毫秒数,返回当前网页DOM结构结束解析、开始加载内嵌资源时(即Document.readyState属性变为“interactive
|
|
130
|
+
/** 是一个无符号long long 型的毫秒数,返回当前网页DOM结构结束解析、开始加载内嵌资源时(即Document.readyState属性变为“interactive”、
|
|
131
|
+
* 相应的readystatechange (en-US)事件触发时)的Unix毫秒时间戳。 */
|
|
129
132
|
domInteractive: string;
|
|
130
133
|
/** 是一个无符号long long 型的毫秒数,返回当前网页DOM结构开始解析时(即Document.readyState属性变为“loading”、相应的 readystatechange (en-US)事件触发时)的Unix毫秒时间戳。 */
|
|
131
134
|
domLoading: string;
|
|
132
|
-
/** 是一个无符号long long 型的毫秒数,表征了域名查询结束的UNIX时间戳。如果使用了持续连接(persistent connection)
|
|
135
|
+
/** 是一个无符号long long 型的毫秒数,表征了域名查询结束的UNIX时间戳。如果使用了持续连接(persistent connection),
|
|
136
|
+
* 或者这个信息存储到了缓存或者本地资源上,这个值将和 PerformanceTiming.fetchStart一致。 */
|
|
133
137
|
domainLookupEnd: string;
|
|
134
|
-
/** 是一个无符号long long 型的毫秒数,表征了域名查询开始的UNIX时间戳。如果使用了持续连接(persistent connection)
|
|
138
|
+
/** 是一个无符号long long 型的毫秒数,表征了域名查询开始的UNIX时间戳。如果使用了持续连接(persistent connection),
|
|
139
|
+
* 或者这个信息存储到了缓存或者本地资源上,这个值将和 PerformanceTiming.fetchStart一致。 */
|
|
135
140
|
domainLookupStart: string;
|
|
136
141
|
/** 是一个无符号long long 型的毫秒数,表征了浏览器准备好使用HTTP请求来获取(fetch)文档的UNIX时间戳。这个时间点会在检查任何应用缓存之前。 */
|
|
137
142
|
fetchStart: string;
|
|
@@ -153,9 +158,11 @@ export declare const reportMap: {
|
|
|
153
158
|
responseStart: string;
|
|
154
159
|
/** 是一个无符号long long 型的毫秒数,返回浏览器与服务器开始安全链接的握手时的Unix毫秒时间戳。如果当前网页不要求安全连接,则返回0。 */
|
|
155
160
|
secureConnectionStart: string;
|
|
156
|
-
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件处理完成时的UNIX时间戳。如果没有上一个文档,
|
|
161
|
+
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件处理完成时的UNIX时间戳。如果没有上一个文档,
|
|
162
|
+
* or if the previous document, or one of the needed redirects, is not of the same origin, 这个值会返回0. */
|
|
157
163
|
unloadEventEnd: string;
|
|
158
|
-
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件抛出时的UNIX时间戳。如果没有上一个文档,
|
|
164
|
+
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件抛出时的UNIX时间戳。如果没有上一个文档,
|
|
165
|
+
* or if the previous document, or one of the needed redirects, is not of the same origin, 这个值会返回0. */
|
|
159
166
|
unloadEventStart: string;
|
|
160
167
|
};
|
|
161
168
|
};
|
|
@@ -175,6 +182,10 @@ export declare const reportMap: {
|
|
|
175
182
|
reason: string;
|
|
176
183
|
/** 上报时带上的详细信息 */
|
|
177
184
|
detail: string;
|
|
185
|
+
/** 上报时带上的请求参数 */
|
|
186
|
+
requestData: string;
|
|
187
|
+
/** 上报时带上的请求方法 */
|
|
188
|
+
method: string;
|
|
178
189
|
};
|
|
179
190
|
vD: {
|
|
180
191
|
/** 埋点名称 */
|
package/cjs/types/global.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IErrorInfo, INavigator, IPv, IUserActivity
|
|
1
|
+
import { IErrorInfo, INavigator, IPerformance, IPv, IUserActivity } from '.';
|
|
2
2
|
/**
|
|
3
3
|
* @description 上报信息
|
|
4
4
|
*/
|
|
@@ -34,9 +34,23 @@ export interface IReport extends INavigator {
|
|
|
34
34
|
/** dpr */
|
|
35
35
|
dpr: number;
|
|
36
36
|
pv: IPv | null;
|
|
37
|
+
lag: {
|
|
38
|
+
lagTime: number;
|
|
39
|
+
} | null;
|
|
37
40
|
error: IErrorInfo | null;
|
|
38
41
|
ua: IUserActivity | null;
|
|
39
42
|
perf: IPerformance | null;
|
|
43
|
+
req: {
|
|
44
|
+
requestType: string;
|
|
45
|
+
responseURL: string;
|
|
46
|
+
status: number;
|
|
47
|
+
loadTime: number;
|
|
48
|
+
statusText: string;
|
|
49
|
+
reason: 'slow' | 'failed' | string;
|
|
50
|
+
detail: string;
|
|
51
|
+
requestData: string;
|
|
52
|
+
method: string;
|
|
53
|
+
} | null;
|
|
40
54
|
vD?: {
|
|
41
55
|
/** 埋点名称 */
|
|
42
56
|
trackName: string;
|
|
@@ -64,7 +78,7 @@ export interface IReport extends INavigator {
|
|
|
64
78
|
* @type visual 可视化埋点上报
|
|
65
79
|
* @type manual 手动上报
|
|
66
80
|
*/
|
|
67
|
-
export type IType = 'pv' | 'error' | 'ua' | 'api' | 'per' | 'init' | 'request' | 'visual' | 'manual';
|
|
81
|
+
export type IType = 'pv' | 'error' | 'ua' | 'api' | 'per' | 'init' | 'request' | 'visual' | 'manual' | 'lag';
|
|
68
82
|
export interface Navigator {
|
|
69
83
|
connection: any;
|
|
70
84
|
}
|
package/cjs/types/index.d.ts
CHANGED
|
@@ -153,13 +153,16 @@ export interface IPerformance {
|
|
|
153
153
|
domContentLoadedEventEnd: number;
|
|
154
154
|
/** 是一个无符号long long 型的毫秒数,返回当解析器发送DOMContentLoaded (en-US) 事件,即所有需要被执行的脚本已经被解析时的Unix毫秒时间戳。 */
|
|
155
155
|
domContentLoadedEventStart: number;
|
|
156
|
-
/** 是一个无符号long long 型的毫秒数,返回当前网页DOM结构结束解析、开始加载内嵌资源时(即Document.readyState属性变为“interactive
|
|
156
|
+
/** 是一个无符号long long 型的毫秒数,返回当前网页DOM结构结束解析、开始加载内嵌资源时(即Document.readyState属性变为“interactive”、
|
|
157
|
+
* 相应的readystatechange (en-US)事件触发时)的Unix毫秒时间戳。 */
|
|
157
158
|
domInteractive: number;
|
|
158
159
|
/** 是一个无符号long long 型的毫秒数,返回当前网页DOM结构开始解析时(即Document.readyState属性变为“loading”、相应的 readystatechange (en-US)事件触发时)的Unix毫秒时间戳。 */
|
|
159
160
|
domLoading: number;
|
|
160
|
-
/** 是一个无符号long long 型的毫秒数,表征了域名查询结束的UNIX时间戳。如果使用了持续连接(persistent connection)
|
|
161
|
+
/** 是一个无符号long long 型的毫秒数,表征了域名查询结束的UNIX时间戳。如果使用了持续连接(persistent connection),
|
|
162
|
+
* 或者这个信息存储到了缓存或者本地资源上,这个值将和 PerformanceTiming.fetchStart一致。 */
|
|
161
163
|
domainLookupEnd: number;
|
|
162
|
-
/** 是一个无符号long long 型的毫秒数,表征了域名查询开始的UNIX时间戳。如果使用了持续连接(persistent connection)
|
|
164
|
+
/** 是一个无符号long long 型的毫秒数,表征了域名查询开始的UNIX时间戳。如果使用了持续连接(persistent connection),
|
|
165
|
+
* 或者这个信息存储到了缓存或者本地资源上,这个值将和 PerformanceTiming.fetchStart一致。 */
|
|
163
166
|
domainLookupStart: number;
|
|
164
167
|
/** 是一个无符号long long 型的毫秒数,表征了浏览器准备好使用HTTP请求来获取(fetch)文档的UNIX时间戳。这个时间点会在检查任何应用缓存之前。 */
|
|
165
168
|
fetchStart: number;
|
|
@@ -181,9 +184,11 @@ export interface IPerformance {
|
|
|
181
184
|
responseStart: number;
|
|
182
185
|
/** 是一个无符号long long 型的毫秒数,返回浏览器与服务器开始安全链接的握手时的Unix毫秒时间戳。如果当前网页不要求安全连接,则返回0。 */
|
|
183
186
|
secureConnectionStart: number;
|
|
184
|
-
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件处理完成时的UNIX时间戳。如果没有上一个文档,
|
|
187
|
+
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件处理完成时的UNIX时间戳。如果没有上一个文档,
|
|
188
|
+
* or if the previous document, or one of the needed redirects, is not of the same origin, 这个值会返回0. */
|
|
185
189
|
unloadEventEnd: number;
|
|
186
|
-
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件抛出时的UNIX时间戳。如果没有上一个文档,
|
|
190
|
+
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件抛出时的UNIX时间戳。如果没有上一个文档,
|
|
191
|
+
* or if the previous document, or one of the needed redirects, is not of the same origin, 这个值会返回0. */
|
|
187
192
|
unloadEventStart: number;
|
|
188
193
|
};
|
|
189
194
|
}
|
package/esm/config/global.js
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import { v4 } from 'uuid';
|
|
2
|
+
import { version } from '../package.json.js';
|
|
3
|
+
import { setRouteStack, setPVTime } from '../handlers/pv.js';
|
|
2
4
|
import { report } from '../reporter.js';
|
|
3
5
|
import { getSessionId, getNavigator, getViewport, getUid } from '../utils/index.js';
|
|
4
|
-
import { setRouteStack, setPVTime } from '../handlers/pv.js';
|
|
5
6
|
import { Config } from './index.js';
|
|
6
|
-
import { version } from '../package.json.js';
|
|
7
7
|
|
|
8
|
-
/*
|
|
9
|
-
* @Author: Mark.Zhang
|
|
10
|
-
* @Date: 2020-10-26 15:40:16
|
|
11
|
-
* @Description 全局配置项
|
|
12
|
-
*/
|
|
13
8
|
// 上报数据
|
|
14
9
|
let Report = {
|
|
15
10
|
uuid: '',
|
|
@@ -35,8 +30,10 @@ let Report = {
|
|
|
35
30
|
pageTitle: '',
|
|
36
31
|
referrer: '',
|
|
37
32
|
pv: null,
|
|
33
|
+
lag: null,
|
|
38
34
|
ua: null,
|
|
39
35
|
error: null,
|
|
36
|
+
req: null,
|
|
40
37
|
dpr: 1,
|
|
41
38
|
perf: null,
|
|
42
39
|
vD: undefined,
|
|
@@ -76,9 +73,10 @@ function initReportFunc() {
|
|
|
76
73
|
*/
|
|
77
74
|
function setReportValue(key, value) {
|
|
78
75
|
if (Object.prototype.hasOwnProperty.call(Report, key)) {
|
|
79
|
-
if (['pv', 'ua', 'error', 'request'].includes(key)) {
|
|
76
|
+
if (['pv', 'ua', 'error', 'request', 'lag'].includes(key)) {
|
|
80
77
|
Report = Object.assign(Object.assign({}, Report), {
|
|
81
78
|
pv: null,
|
|
79
|
+
lag: null,
|
|
82
80
|
ua: null,
|
|
83
81
|
error: null,
|
|
84
82
|
req: null,
|
|
@@ -95,11 +93,12 @@ function setReportValue(key, value) {
|
|
|
95
93
|
function getReport() {
|
|
96
94
|
const nav = getNavigator();
|
|
97
95
|
const viewport = getViewport();
|
|
96
|
+
const uuid = localStorage.getItem('username') || getUid();
|
|
98
97
|
return Object.assign(Object.assign(Object.assign({}, Report), nav), {
|
|
99
98
|
version,
|
|
100
99
|
projectID: Config.projectID,
|
|
101
100
|
host: location.host,
|
|
102
|
-
uuid
|
|
101
|
+
uuid,
|
|
103
102
|
viewport,
|
|
104
103
|
screen: `${screen.width} x ${screen.height}`,
|
|
105
104
|
pageTitle: document.title,
|
|
@@ -138,7 +137,9 @@ const tempUrlInfo = {};
|
|
|
138
137
|
const recordXMLHttpRequestLog = (XMLHttpRequestTimeout) => {
|
|
139
138
|
XMLHttpRequestTimeout = typeof XMLHttpRequestTimeout === 'number' ? XMLHttpRequestTimeout : 1000;
|
|
140
139
|
const timeRecordArray = [];
|
|
140
|
+
//@ts-ignore
|
|
141
141
|
window.__XMLHttpRequest__ = window.XMLHttpRequest;
|
|
142
|
+
//@ts-ignore
|
|
142
143
|
window.XMLHttpRequest = newXHR;
|
|
143
144
|
window.addEventListener('ajaxLoadStart', function (e) {
|
|
144
145
|
const tempObj = {
|
|
@@ -163,10 +164,12 @@ const recordXMLHttpRequestLog = (XMLHttpRequestTimeout) => {
|
|
|
163
164
|
statusText,
|
|
164
165
|
reason: '',
|
|
165
166
|
detail: '',
|
|
167
|
+
requestData: '',
|
|
168
|
+
method: '',
|
|
166
169
|
};
|
|
167
170
|
if (loadTime && loadTime > XMLHttpRequestTimeout) {
|
|
168
171
|
request.reason = 'slow';
|
|
169
|
-
request.detail = `request is too slow, XMLHttpRequestTimeout: ${
|
|
172
|
+
request.detail = `request is too slow, XMLHttpRequestTimeout: ${loadTime}`;
|
|
170
173
|
}
|
|
171
174
|
else if (status && status >= 300 && statusText && statusText.toLowerCase() !== 'ok') {
|
|
172
175
|
request.reason = 'failed';
|
|
@@ -199,6 +202,7 @@ const hackFetch = (XMLHttpRequestTimeout) => {
|
|
|
199
202
|
if (typeof window.fetch === 'function') {
|
|
200
203
|
const __fetch__ = window.fetch;
|
|
201
204
|
window.__fetch__ = __fetch__;
|
|
205
|
+
//@ts-ignore
|
|
202
206
|
window.fetch = function (t, ...args) {
|
|
203
207
|
const begin = Date.now();
|
|
204
208
|
//禁用数组的扩展运算符,否则portal的生产环境会报Uncaught TypeError: Object(...) is not a function,
|
|
@@ -229,6 +233,8 @@ const hackFetch = (XMLHttpRequestTimeout) => {
|
|
|
229
233
|
statusText,
|
|
230
234
|
reason: '',
|
|
231
235
|
detail: '',
|
|
236
|
+
requestData: '',
|
|
237
|
+
method: '',
|
|
232
238
|
};
|
|
233
239
|
if (!ok || status >= 300) {
|
|
234
240
|
request.reason = 'failed';
|
|
@@ -236,7 +242,7 @@ const hackFetch = (XMLHttpRequestTimeout) => {
|
|
|
236
242
|
}
|
|
237
243
|
else if (loadTime > XMLHttpRequestTimeout) {
|
|
238
244
|
request.reason = 'slow';
|
|
239
|
-
request.detail = `request is too slow, XMLHttpRequestTimeout: ${
|
|
245
|
+
request.detail = `request is too slow, XMLHttpRequestTimeout: ${loadTime}, result: ${result === null || result === void 0 ? void 0 : result.slice(0, 500)}`;
|
|
240
246
|
}
|
|
241
247
|
if (request.reason) {
|
|
242
248
|
if (!tempUrlInfo[url]) {
|
package/esm/config/index.d.ts
CHANGED
|
@@ -23,10 +23,6 @@ export declare function getConfigValue(key: keyof IConfig): string | number | bo
|
|
|
23
23
|
urls?: string[] | undefined;
|
|
24
24
|
errors?: (string | {
|
|
25
25
|
regExp: boolean;
|
|
26
|
-
/**
|
|
27
|
-
* @description 设置config配置项
|
|
28
|
-
* @param config 配置项
|
|
29
|
-
*/
|
|
30
26
|
input: string;
|
|
31
27
|
})[] | undefined;
|
|
32
28
|
apis?: string[] | undefined;
|
package/esm/config/index.js
CHANGED
package/esm/constant.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const
|
|
2
|
-
export declare const
|
|
1
|
+
export declare const monitorTrackId = "monitor-track-id";
|
|
2
|
+
export declare const monitorTrackSessionId = "monitor-track-session-id";
|
package/esm/constant.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
1
|
+
const monitorTrackId = 'monitor-track-id';
|
|
2
|
+
const monitorTrackSessionId = 'monitor-track-session-id';
|
|
3
3
|
|
|
4
|
-
export {
|
|
4
|
+
export { monitorTrackId, monitorTrackSessionId };
|
package/esm/handlers/error.js
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import * as rrweb from 'rrweb';
|
|
2
1
|
import ErrorStackParser from 'error-stack-parser';
|
|
3
2
|
import html2canvas from 'html2canvas';
|
|
3
|
+
import * as rrweb from 'rrweb';
|
|
4
4
|
import { v4 } from 'uuid';
|
|
5
|
-
import { report } from '../reporter.js';
|
|
6
|
-
import { setReportValue, getReport } from '../config/global.js';
|
|
7
5
|
import { Config } from '../config/index.js';
|
|
6
|
+
import { setReportValue, getReport } from '../config/global.js';
|
|
7
|
+
import { report } from '../reporter.js';
|
|
8
8
|
|
|
9
|
-
/*
|
|
10
|
-
* @Author: Mark.Zhang
|
|
11
|
-
* @Date: 2020-10-26 11:10:04
|
|
12
|
-
* @Description 资源加载错误及js错误相关的处理方法
|
|
13
|
-
*/
|
|
14
9
|
const eventsMatrix = [[]];
|
|
15
10
|
rrweb.record({
|
|
16
11
|
emit(event, isCheckout) {
|
package/esm/handlers/pv.d.ts
CHANGED
package/esm/handlers/pv.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
+
import { Config } from '../config/index.js';
|
|
1
2
|
import { setReportValue, getReport } from '../config/global.js';
|
|
2
3
|
import { report } from '../reporter.js';
|
|
3
|
-
import { Config } from '../config/index.js';
|
|
4
4
|
import { visualTrackFunc } from '../utils/index.js';
|
|
5
5
|
|
|
6
|
-
/* eslint-disable prefer-rest-params */
|
|
7
6
|
/** 路由栈数组,存储路由变化信息 */
|
|
8
7
|
let routerStack = [];
|
|
9
8
|
/** 路由触发的时间 */
|
|
@@ -16,9 +15,11 @@ function _history(type) {
|
|
|
16
15
|
const origin = history[type];
|
|
17
16
|
return function () {
|
|
18
17
|
// @ts-ignore
|
|
18
|
+
// eslint-disable-next-line prefer-rest-params
|
|
19
19
|
const r = origin.apply(this, arguments);
|
|
20
20
|
const e = new Event(type);
|
|
21
21
|
// @ts-ignore
|
|
22
|
+
// eslint-disable-next-line prefer-rest-params
|
|
22
23
|
e.arguments = arguments;
|
|
23
24
|
window.dispatchEvent(e);
|
|
24
25
|
return r;
|
|
@@ -30,12 +31,12 @@ function _history(type) {
|
|
|
30
31
|
*/
|
|
31
32
|
function handleHistoryChange(__e) {
|
|
32
33
|
visualTrackFunc();
|
|
33
|
-
setReport();
|
|
34
|
+
setReport({ type: 'pv' });
|
|
34
35
|
}
|
|
35
36
|
/**
|
|
36
37
|
* 设置信息并触发上报
|
|
37
38
|
*/
|
|
38
|
-
function setReport() {
|
|
39
|
+
function setReport({ type, lagTime }) {
|
|
39
40
|
let pageUrl = location.href;
|
|
40
41
|
/**
|
|
41
42
|
* 此判断的逻辑是因为spa且hash模式下,路由搜索参数更改也会触发handleHistoryChange事件
|
|
@@ -58,7 +59,7 @@ function setReport() {
|
|
|
58
59
|
}
|
|
59
60
|
const { originPage, page } = setRouteStack(pageUrl);
|
|
60
61
|
// 愿页面等于当前页面,说明无路由变更。只有spa且hash模式下才会出现
|
|
61
|
-
if (originPage === page) {
|
|
62
|
+
if (originPage === page && type === 'pv') {
|
|
62
63
|
return;
|
|
63
64
|
}
|
|
64
65
|
const currentTime = new Date().getTime();
|
|
@@ -69,8 +70,14 @@ function setReport() {
|
|
|
69
70
|
// 设置信息
|
|
70
71
|
setReportValue('originPage', originPage);
|
|
71
72
|
setReportValue('page', page);
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
if (type === 'pv') {
|
|
74
|
+
setReportValue('type', 'pv');
|
|
75
|
+
setReportValue('pv', { stayTime });
|
|
76
|
+
}
|
|
77
|
+
else if (type === 'lag') {
|
|
78
|
+
setReportValue('type', 'lag');
|
|
79
|
+
setReportValue('lag', { lagTime: lagTime });
|
|
80
|
+
}
|
|
74
81
|
// 上报数据
|
|
75
82
|
report(getReport());
|
|
76
83
|
}
|
|
@@ -94,6 +101,10 @@ function setRouteStack(page) {
|
|
|
94
101
|
originPage: routerStack[0],
|
|
95
102
|
page: routerStack[1] || routerStack[0],
|
|
96
103
|
};
|
|
104
|
+
}
|
|
105
|
+
function handlePageLag(lagTime) {
|
|
106
|
+
// console.log('检测到页面卡顿', lagTime);
|
|
107
|
+
setReport({ type: 'lag', lagTime });
|
|
97
108
|
}
|
|
98
109
|
|
|
99
|
-
export { _history, handleHistoryChange, setPVTime, setRouteStack };
|
|
110
|
+
export { _history, handleHistoryChange, handlePageLag, setPVTime, setRouteStack };
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import { getElmPath } from '../utils/index.js';
|
|
2
|
-
import { report } from '../reporter.js';
|
|
3
1
|
import { setReportValue, getReport } from '../config/global.js';
|
|
2
|
+
import { report } from '../reporter.js';
|
|
3
|
+
import { getElmPath } from '../utils/index.js';
|
|
4
4
|
|
|
5
|
-
/*
|
|
6
|
-
* @Author: Mark.Zhang
|
|
7
|
-
* @Date: 2020-10-26 11:10:04
|
|
8
|
-
* @Description 用户行为处理方法
|
|
9
|
-
*/
|
|
10
5
|
/**
|
|
11
6
|
* @description 点击事件触发后的操作
|
|
12
7
|
*/
|
package/esm/index.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { IConfig } from './types/config';
|
|
2
3
|
export default class Track {
|
|
4
|
+
lagTimer: NodeJS.Timeout | null;
|
|
5
|
+
observer: PerformanceObserver | null;
|
|
3
6
|
init(config: IConfig): void;
|
|
4
7
|
visualTrack: () => void;
|
|
8
|
+
listenPageLag: () => void;
|
|
5
9
|
/**
|
|
6
10
|
* @description 监听错误异常
|
|
7
11
|
*/
|
package/esm/index.js
CHANGED
|
@@ -1,18 +1,30 @@
|
|
|
1
|
-
import { initWindowObjectFunction, on, off, visualTrackFunc, handleLocationChange } from './utils/index.js';
|
|
2
1
|
import { setConfig, Config } from './config/index.js';
|
|
3
2
|
import { initReport, recordXMLHttpRequestLog, hackFetch } from './config/global.js';
|
|
4
|
-
import {
|
|
3
|
+
import { monitorTrackSessionId } from './constant.js';
|
|
4
|
+
import { handlePageLag, _history, handleHistoryChange } from './handlers/pv.js';
|
|
5
5
|
import { handleError } from './handlers/error.js';
|
|
6
6
|
import { handleClick, handleBlur, handleScroll } from './handlers/user-activity.js';
|
|
7
|
-
import {
|
|
7
|
+
import { initWindowObjectFunction, on, off, visualTrackFunc, handleLocationChange } from './utils/index.js';
|
|
8
8
|
|
|
9
9
|
class Track {
|
|
10
10
|
constructor() {
|
|
11
|
+
this.lagTimer = null;
|
|
12
|
+
this.observer = null;
|
|
11
13
|
this.visualTrack = () => {
|
|
12
14
|
window.onload = () => {
|
|
13
15
|
visualTrackFunc();
|
|
14
16
|
};
|
|
15
17
|
};
|
|
18
|
+
this.listenPageLag = () => {
|
|
19
|
+
this.observer = new PerformanceObserver((list) => {
|
|
20
|
+
list.getEntries().forEach((entry) => {
|
|
21
|
+
if (entry.duration > 400) {
|
|
22
|
+
handlePageLag(entry.duration);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
this.observer.observe({ entryTypes: ['longtask'] });
|
|
27
|
+
};
|
|
16
28
|
}
|
|
17
29
|
init(config) {
|
|
18
30
|
var _a;
|
|
@@ -23,7 +35,7 @@ class Track {
|
|
|
23
35
|
// 没有项目ID,则不监听任何事件
|
|
24
36
|
if (!config.projectID) {
|
|
25
37
|
// eslint-disable-next-line no-console
|
|
26
|
-
console.warn('缺少项目ID或
|
|
38
|
+
console.warn('缺少项目ID或projectID!');
|
|
27
39
|
return;
|
|
28
40
|
}
|
|
29
41
|
// 没有reportUrl
|
|
@@ -43,6 +55,7 @@ class Track {
|
|
|
43
55
|
Config.enableBehavior && this.addListenUserActivity();
|
|
44
56
|
Config.enableError && this.addListenJSUncaught();
|
|
45
57
|
this.visualTrack();
|
|
58
|
+
this.listenPageLag();
|
|
46
59
|
this.addListenUnload();
|
|
47
60
|
initWindowObjectFunction();
|
|
48
61
|
}
|
|
@@ -94,6 +107,7 @@ class Track {
|
|
|
94
107
|
* @description 销毁监听器
|
|
95
108
|
*/
|
|
96
109
|
destroy() {
|
|
110
|
+
var _a;
|
|
97
111
|
if (Config.spa) {
|
|
98
112
|
// off('hashchange', pv.handleHashChange);
|
|
99
113
|
off('pushState', handleHistoryChange);
|
|
@@ -108,7 +122,9 @@ class Track {
|
|
|
108
122
|
if (Config.enableError) {
|
|
109
123
|
off('error', handleError);
|
|
110
124
|
}
|
|
111
|
-
|
|
125
|
+
this.lagTimer && clearInterval(this.lagTimer);
|
|
126
|
+
(_a = this.observer) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
127
|
+
sessionStorage.removeItem(monitorTrackSessionId);
|
|
112
128
|
}
|
|
113
129
|
}
|
|
114
130
|
|
package/esm/package.json.js
CHANGED
package/esm/reporter.d.ts
CHANGED
|
@@ -48,11 +48,13 @@ export declare const reportMap: {
|
|
|
48
48
|
/** 操作系统版本 */
|
|
49
49
|
osVersion: string;
|
|
50
50
|
pv: {
|
|
51
|
-
/** 子类型 */
|
|
52
|
-
subType: string;
|
|
53
51
|
/** 停留时间 */
|
|
54
52
|
stayTime: string;
|
|
55
53
|
};
|
|
54
|
+
lag: {
|
|
55
|
+
/** 页面卡顿时间 */
|
|
56
|
+
lagTime: string;
|
|
57
|
+
};
|
|
56
58
|
error: {
|
|
57
59
|
/** 子类型 */
|
|
58
60
|
subType: string;
|
|
@@ -125,13 +127,16 @@ export declare const reportMap: {
|
|
|
125
127
|
domContentLoadedEventEnd: string;
|
|
126
128
|
/** 是一个无符号long long 型的毫秒数,返回当解析器发送DOMContentLoaded (en-US) 事件,即所有需要被执行的脚本已经被解析时的Unix毫秒时间戳。 */
|
|
127
129
|
domContentLoadedEventStart: string;
|
|
128
|
-
/** 是一个无符号long long 型的毫秒数,返回当前网页DOM结构结束解析、开始加载内嵌资源时(即Document.readyState属性变为“interactive
|
|
130
|
+
/** 是一个无符号long long 型的毫秒数,返回当前网页DOM结构结束解析、开始加载内嵌资源时(即Document.readyState属性变为“interactive”、
|
|
131
|
+
* 相应的readystatechange (en-US)事件触发时)的Unix毫秒时间戳。 */
|
|
129
132
|
domInteractive: string;
|
|
130
133
|
/** 是一个无符号long long 型的毫秒数,返回当前网页DOM结构开始解析时(即Document.readyState属性变为“loading”、相应的 readystatechange (en-US)事件触发时)的Unix毫秒时间戳。 */
|
|
131
134
|
domLoading: string;
|
|
132
|
-
/** 是一个无符号long long 型的毫秒数,表征了域名查询结束的UNIX时间戳。如果使用了持续连接(persistent connection)
|
|
135
|
+
/** 是一个无符号long long 型的毫秒数,表征了域名查询结束的UNIX时间戳。如果使用了持续连接(persistent connection),
|
|
136
|
+
* 或者这个信息存储到了缓存或者本地资源上,这个值将和 PerformanceTiming.fetchStart一致。 */
|
|
133
137
|
domainLookupEnd: string;
|
|
134
|
-
/** 是一个无符号long long 型的毫秒数,表征了域名查询开始的UNIX时间戳。如果使用了持续连接(persistent connection)
|
|
138
|
+
/** 是一个无符号long long 型的毫秒数,表征了域名查询开始的UNIX时间戳。如果使用了持续连接(persistent connection),
|
|
139
|
+
* 或者这个信息存储到了缓存或者本地资源上,这个值将和 PerformanceTiming.fetchStart一致。 */
|
|
135
140
|
domainLookupStart: string;
|
|
136
141
|
/** 是一个无符号long long 型的毫秒数,表征了浏览器准备好使用HTTP请求来获取(fetch)文档的UNIX时间戳。这个时间点会在检查任何应用缓存之前。 */
|
|
137
142
|
fetchStart: string;
|
|
@@ -153,9 +158,11 @@ export declare const reportMap: {
|
|
|
153
158
|
responseStart: string;
|
|
154
159
|
/** 是一个无符号long long 型的毫秒数,返回浏览器与服务器开始安全链接的握手时的Unix毫秒时间戳。如果当前网页不要求安全连接,则返回0。 */
|
|
155
160
|
secureConnectionStart: string;
|
|
156
|
-
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件处理完成时的UNIX时间戳。如果没有上一个文档,
|
|
161
|
+
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件处理完成时的UNIX时间戳。如果没有上一个文档,
|
|
162
|
+
* or if the previous document, or one of the needed redirects, is not of the same origin, 这个值会返回0. */
|
|
157
163
|
unloadEventEnd: string;
|
|
158
|
-
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件抛出时的UNIX时间戳。如果没有上一个文档,
|
|
164
|
+
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件抛出时的UNIX时间戳。如果没有上一个文档,
|
|
165
|
+
* or if the previous document, or one of the needed redirects, is not of the same origin, 这个值会返回0. */
|
|
159
166
|
unloadEventStart: string;
|
|
160
167
|
};
|
|
161
168
|
};
|
|
@@ -175,6 +182,10 @@ export declare const reportMap: {
|
|
|
175
182
|
reason: string;
|
|
176
183
|
/** 上报时带上的详细信息 */
|
|
177
184
|
detail: string;
|
|
185
|
+
/** 上报时带上的请求参数 */
|
|
186
|
+
requestData: string;
|
|
187
|
+
/** 上报时带上的请求方法 */
|
|
188
|
+
method: string;
|
|
178
189
|
};
|
|
179
190
|
vD: {
|
|
180
191
|
/** 埋点名称 */
|
package/esm/reporter.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { v4 } from 'uuid';
|
|
2
|
-
import { serialize } from './utils/index.js';
|
|
3
|
-
import { getFullScreenShoot } from './handlers/error.js';
|
|
4
2
|
import { Config } from './config/index.js';
|
|
3
|
+
import { getFullScreenShoot } from './handlers/error.js';
|
|
4
|
+
import { serialize } from './utils/index.js';
|
|
5
5
|
|
|
6
6
|
/** 上报数据映射 */
|
|
7
7
|
const reportMap = {
|
|
@@ -52,11 +52,13 @@ const reportMap = {
|
|
|
52
52
|
/** 操作系统版本 */
|
|
53
53
|
osVersion: 'osV',
|
|
54
54
|
pv: {
|
|
55
|
-
/** 子类型 */
|
|
56
|
-
subType: 'suT',
|
|
57
55
|
/** 停留时间 */
|
|
58
56
|
stayTime: 'sT',
|
|
59
57
|
},
|
|
58
|
+
lag: {
|
|
59
|
+
/** 页面卡顿时间 */
|
|
60
|
+
lagTime: 'lT',
|
|
61
|
+
},
|
|
60
62
|
error: {
|
|
61
63
|
/** 子类型 */
|
|
62
64
|
subType: 'suT',
|
|
@@ -129,13 +131,16 @@ const reportMap = {
|
|
|
129
131
|
domContentLoadedEventEnd: 'scLee',
|
|
130
132
|
/** 是一个无符号long long 型的毫秒数,返回当解析器发送DOMContentLoaded (en-US) 事件,即所有需要被执行的脚本已经被解析时的Unix毫秒时间戳。 */
|
|
131
133
|
domContentLoadedEventStart: 'dcLes',
|
|
132
|
-
/** 是一个无符号long long 型的毫秒数,返回当前网页DOM结构结束解析、开始加载内嵌资源时(即Document.readyState属性变为“interactive
|
|
134
|
+
/** 是一个无符号long long 型的毫秒数,返回当前网页DOM结构结束解析、开始加载内嵌资源时(即Document.readyState属性变为“interactive”、
|
|
135
|
+
* 相应的readystatechange (en-US)事件触发时)的Unix毫秒时间戳。 */
|
|
133
136
|
domInteractive: 'di',
|
|
134
137
|
/** 是一个无符号long long 型的毫秒数,返回当前网页DOM结构开始解析时(即Document.readyState属性变为“loading”、相应的 readystatechange (en-US)事件触发时)的Unix毫秒时间戳。 */
|
|
135
138
|
domLoading: 'dl',
|
|
136
|
-
/** 是一个无符号long long 型的毫秒数,表征了域名查询结束的UNIX时间戳。如果使用了持续连接(persistent connection)
|
|
139
|
+
/** 是一个无符号long long 型的毫秒数,表征了域名查询结束的UNIX时间戳。如果使用了持续连接(persistent connection),
|
|
140
|
+
* 或者这个信息存储到了缓存或者本地资源上,这个值将和 PerformanceTiming.fetchStart一致。 */
|
|
137
141
|
domainLookupEnd: 'dle',
|
|
138
|
-
/** 是一个无符号long long 型的毫秒数,表征了域名查询开始的UNIX时间戳。如果使用了持续连接(persistent connection)
|
|
142
|
+
/** 是一个无符号long long 型的毫秒数,表征了域名查询开始的UNIX时间戳。如果使用了持续连接(persistent connection),
|
|
143
|
+
* 或者这个信息存储到了缓存或者本地资源上,这个值将和 PerformanceTiming.fetchStart一致。 */
|
|
139
144
|
domainLookupStart: 'dls',
|
|
140
145
|
/** 是一个无符号long long 型的毫秒数,表征了浏览器准备好使用HTTP请求来获取(fetch)文档的UNIX时间戳。这个时间点会在检查任何应用缓存之前。 */
|
|
141
146
|
fetchStart: 'fs',
|
|
@@ -157,9 +162,11 @@ const reportMap = {
|
|
|
157
162
|
responseStart: 'resS',
|
|
158
163
|
/** 是一个无符号long long 型的毫秒数,返回浏览器与服务器开始安全链接的握手时的Unix毫秒时间戳。如果当前网页不要求安全连接,则返回0。 */
|
|
159
164
|
secureConnectionStart: 'scs',
|
|
160
|
-
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件处理完成时的UNIX时间戳。如果没有上一个文档,
|
|
165
|
+
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件处理完成时的UNIX时间戳。如果没有上一个文档,
|
|
166
|
+
* or if the previous document, or one of the needed redirects, is not of the same origin, 这个值会返回0. */
|
|
161
167
|
unloadEventEnd: 'uee',
|
|
162
|
-
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件抛出时的UNIX时间戳。如果没有上一个文档,
|
|
168
|
+
/** 是一个无符号long long 型的毫秒数,表征了unload (en-US)事件抛出时的UNIX时间戳。如果没有上一个文档,
|
|
169
|
+
* or if the previous document, or one of the needed redirects, is not of the same origin, 这个值会返回0. */
|
|
163
170
|
unloadEventStart: 'ees',
|
|
164
171
|
},
|
|
165
172
|
},
|
|
@@ -179,6 +186,10 @@ const reportMap = {
|
|
|
179
186
|
reason: 're',
|
|
180
187
|
/** 上报时带上的详细信息 */
|
|
181
188
|
detail: 'de',
|
|
189
|
+
/** 上报时带上的请求参数 */
|
|
190
|
+
requestData: 'rD',
|
|
191
|
+
/** 上报时带上的请求方法 */
|
|
192
|
+
method: 'rM',
|
|
182
193
|
},
|
|
183
194
|
vD: {
|
|
184
195
|
/** 埋点名称 */
|
|
@@ -214,7 +225,6 @@ const xhrFunc = (filename, userId, asyncUpdateId, file, res, callback, rest) =>
|
|
|
214
225
|
callback((_a = resp.result) === null || _a === void 0 ? void 0 : _a.response);
|
|
215
226
|
}
|
|
216
227
|
catch (_err) {
|
|
217
|
-
//
|
|
218
228
|
}
|
|
219
229
|
res();
|
|
220
230
|
}
|