前端性能监控 SDK 搭建
前端性能监控 SDK 搭建
核心目标
实现:
- 监控性能指标和资源加载。
- 捕获错误。
- 上报数据。
1:初始化项目
1
2
3
4
mkdir performance-sdk
cd performance-sdk
npm init -y
npm install rollup --save-dev
2:设计 SDK 结构
1
2
3
4
5
6
7
8
9
performance-sdk/
├── src/
│ ├── index.js # 主入口
│ ├── performance.js # 性能监控模块
│ ├── resource.js # 资源监控模块
│ ├── error.js # 错误监控模块
│ └── report.js # 数据上报模块
├── rollup.config.js
└── package.json
3:实现性能监控
在 src/performance.js
中,使用 Performance API 和 Web Vitals 指标:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
export class PerformanceMonitor {
constructor() {
this.metrics = {};
this.init();
}
init() {
// 指标
window.addEventListener('load', () => {
const timing = performance.timing;
this.metrics = {
dns: timing.domainLookupEnd - timing.domainLookupStart,
tcp: timing.connectEnd - timing.connectStart,
request: timing.responseEnd - timing.requestStart,
dom: timing.domContentLoadedEventEnd - timing.domLoading,
load: timing.loadEventEnd - timing.navigationStart
};
});
}
getMetrics() {
return this.metrics;
}
}
4:监控资源加载
在 src/resource.js
中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
export class ResourceMonitor {
constructor() {
this.resources = [];
this.init();
}
init() {
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
if (entry.initiatorType === 'script' || entry.initiatorType === 'css') {
this.resources.push({
name: entry.name,
duration: entry.duration,
type: entry.initiatorType
});
}
});
});
observer.observe({ entryTypes: ['resource'] });
}
getResources() {
return this.resources;
}
}
5:捕获错误
在 src/error.js
中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
export class ErrorMonitor {
constructor() {
this.errors = [];
this.init();
}
init() {
window.addEventListener('error', (event) => {
this.errors.push({
message: event.message,
file: event.filename,
line: event.lineno,
column: event.colno,
time: new Date().toISOString()
});
});
}
getErrors() {
return this.errors;
}
}
6:数据上报
在 src/report.js
中:
1
2
3
4
5
6
7
8
9
10
export class Reporter {
constructor(url) {
this.url = url;
}
send(data) {
const payload = JSON.stringify(data);
navigator.sendBeacon(this.url, payload);
}
}
7:整合 SDK
在 src/index.js
中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { PerformanceMonitor } from './performance.js';
import { ResourceMonitor } from './resource.js';
import { ErrorMonitor } from './error.js';
import { Reporter } from './report.js';
export class PerformanceSDK {
constructor({ reportUrl }) {
this.performance = new PerformanceMonitor();
this.resource = new ResourceMonitor();
this.error = new ErrorMonitor();
this.reporter = new Reporter(reportUrl);
this.reportInterval = null;
}
start() {
this.reportInterval = setInterval(() => {
const data = {
performance: this.performance.getMetrics(),
resources: this.resource.getResources(),
errors: this.error.getErrors()
};
this.reporter.send(data);
}, 5000);
}
stop() {
clearInterval(this.reportInterval);
}
}
8:打包 SDK
配置 rollup.config.js
:
1
2
3
4
5
6
7
8
export default {
input: 'src/index.js',
output: {
file: 'dist/performance-sdk.js',
format: 'umd',
name: 'PerformanceSDK'
}
};
运行:
1
npx rollup -c
9:使用 SDK
1
2
3
4
5
<script src="/dist/performance-sdk.js"></script>
<script>
const sdk = new PerformanceSDK({ reportUrl: 'https://example.com/report' });
sdk.start();
</script>
This post is licensed under CC BY 4.0 by the author.