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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
| // CDN性能监控系统
class CDNPerformanceMonitor {
constructor() {
this.metrics = {
latency: [],
throughput: [],
errorRate: [],
cacheHitRate: []
};
this.startMonitoring();
}
startMonitoring() {
// 监控页面加载时间
this.monitorPageLoad();
// 监控资源加载时间
this.monitorResourceLoad();
// 监控API响应时间
this.monitorAPIResponse();
// 监控用户体验指标
this.monitorWebVitals();
}
monitorPageLoad() {
window.addEventListener('load', () => {
const navigation = performance.getEntriesByType('navigation')[0];
const metrics = {
dnsLookup: navigation.domainLookupEnd - navigation.domainLookupStart,
tcpConnect: navigation.connectEnd - navigation.connectStart,
sslHandshake: navigation.secureConnectionStart > 0
? navigation.connectEnd - navigation.secureConnectionStart
: 0,
ttfb: navigation.responseStart - navigation.requestStart,
download: navigation.responseEnd - navigation.responseStart,
domParse: navigation.domContentLoadedEventStart - navigation.responseEnd,
domReady: navigation.domContentLoadedEventEnd - navigation.domContentLoadedEventStart,
pageLoad: navigation.loadEventEnd - navigation.loadEventStart
};
this.recordMetrics('latency', metrics);
this.sendMetrics('page_load', metrics);
});
}
monitorResourceLoad() {
const observer = new PerformanceObserver((list) => {
const entries = list.getEntries();
entries.forEach(entry => {
if (entry.initiatorType === 'resource') {
const resourceMetrics = {
name: entry.name,
type: entry.initiatorType,
duration: entry.duration,
size: entry.transferSize,
cached: entry.transferSize === 0 && entry.decodedBodySize > 0
};
this.sendMetrics('resource_load', resourceMetrics);
}
});
});
observer.observe({ entryTypes: ['resource'] });
}
monitorWebVitals() {
// Largest Contentful Paint (LCP)
this.observeLCP();
// First Input Delay (FID)
this.observeFID();
// Cumulative Layout Shift (CLS)
this.observeCLS();
}
observeLCP() {
new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
const lastEntry = entries[entries.length - 1];
this.sendMetrics('lcp', {
value: lastEntry.renderTime || lastEntry.loadTime,
element: lastEntry.element?.tagName
});
}).observe({ entryTypes: ['largest-contentful-paint'] });
}
observeFID() {
new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
entries.forEach(entry => {
this.sendMetrics('fid', {
value: entry.processingStart - entry.startTime,
inputType: entry.name
});
});
}).observe({ entryTypes: ['first-input'] });
}
observeCLS() {
let clsValue = 0;
new PerformanceObserver((entryList) => {
const entries = entryList.getEntries();
entries.forEach(entry => {
if (!entry.hadRecentInput) {
clsValue += entry.value;
}
});
this.sendMetrics('cls', { value: clsValue });
}).observe({ entryTypes: ['layout-shift'] });
}
sendMetrics(type, data) {
// 发送到CDN分析服务
fetch('/cdn-analytics/metrics', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
type,
data,
timestamp: Date.now(),
userAgent: navigator.userAgent,
url: window.location.href
})
}).catch(error => {
console.warn('Failed to send metrics:', error);
});
}
}
|