Skip to content

Commit 0279f4f

Browse files
committed
Update to latest Obs.js SpeedCurve plugin
1 parent 0829d77 commit 0279f4f

2 files changed

Lines changed: 82 additions & 13 deletions

File tree

‎_layouts/default.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,4 @@
7171
}
7272
</script>
7373

74-
<script src=/js/obs.speedcurve.js?v=0006 type=module></script>
74+
<script src=/js/obs.speedcurve.js?v=0007 type=module></script>

‎js/obs.speedcurve.js‎

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,6 @@
1212

1313
const obs = window.obs || Object.create(null);
1414

15-
const navigation = performance.getEntriesByType('navigation')[0];
16-
17-
const { connection } = navigator;
18-
19-
if (connection && 'rtt' in connection) {
20-
lux.addData('rtt', connection.rtt);
21-
}
22-
2315
// Keys we intend to send. Keep in sync with obs.js
2416
const keys = [
2517
'canShowRichMedia',
@@ -45,9 +37,25 @@
4537
}
4638
}
4739

40+
// Surface the browser-reported static CPU performance tier.
41+
if ('cpuPerformance' in navigator) {
42+
const { cpuPerformance } = navigator;
43+
if (
44+
typeof cpuPerformance === 'number' &&
45+
Number.isFinite(cpuPerformance) &&
46+
Number.isInteger(cpuPerformance) &&
47+
cpuPerformance >= 0
48+
) {
49+
lux.addData('cpuTier', cpuPerformance);
50+
}
51+
}
52+
53+
const navigation = performance.getEntriesByType('navigation')[0];
54+
4855
if (!navigation) return;
4956

50-
// Was the response from HTTP cache or the network?
57+
// Separate locally served documents from those that required network
58+
// transfer.
5159
const { transferSize } = navigation;
5260

5361
if (transferSize === 0) {
@@ -56,16 +64,76 @@
5664
lux.addData('fromCache', false);
5765
}
5866

59-
// Was the response from the back–forward cache?
67+
// Record the final HTTP response status exposed for the navigation.
68+
if ('responseStatus' in navigation) {
69+
const { responseStatus } = navigation;
70+
if (
71+
typeof responseStatus === 'number' &&
72+
Number.isFinite(responseStatus) &&
73+
Number.isInteger(responseStatus) &&
74+
responseStatus > 0
75+
) {
76+
lux.addData('responseStatus', responseStatus);
77+
}
78+
}
79+
80+
// Identify navigations intercepted by a service worker.
81+
if ('workerStart' in navigation) {
82+
const { workerStart } = navigation;
83+
if (typeof workerStart === 'number' && Number.isFinite(workerStart)) {
84+
if (workerStart > 0) {
85+
lux.addData('viaSW', true);
86+
} else if (workerStart === 0) {
87+
lux.addData('viaSW', false);
88+
}
89+
}
90+
}
91+
92+
// Approximate the time spent starting or activating the service worker.
93+
if ('workerStart' in navigation) {
94+
const { fetchStart, workerStart } = navigation;
95+
if (
96+
typeof fetchStart === 'number' &&
97+
Number.isFinite(fetchStart) &&
98+
typeof workerStart === 'number' &&
99+
Number.isFinite(workerStart) &&
100+
workerStart > 0 &&
101+
fetchStart >= workerStart
102+
) {
103+
const swStartupTime = Math.round(fetchStart - workerStart);
104+
if (Number.isFinite(swStartupTime) && swStartupTime >= 0) {
105+
lux.addData('swStartupTime', swStartupTime);
106+
}
107+
}
108+
}
109+
110+
// Keep restored views distinct from conventional navigations in RUM analysis.
60111
window.addEventListener('pageshow', (event) => {
61112
lux.addData('frombfCache', event.persisted);
62113
});
63114

115+
// Preserve prerender history so pre-activation timings remain interpretable.
64116
lux.addData(
65117
'fromPrerender',
66118
document.prerendering || navigation.activationStart > 0
67119
);
68120

121+
// Measure the proportion of HTML body bytes saved by content encoding.
122+
const { decodedBodySize, encodedBodySize } = navigation;
123+
if (
124+
typeof decodedBodySize === 'number' &&
125+
Number.isFinite(decodedBodySize) &&
126+
decodedBodySize > 0 &&
127+
typeof encodedBodySize === 'number' &&
128+
Number.isFinite(encodedBodySize) &&
129+
encodedBodySize > 0
130+
) {
131+
const compressionDelta = 1 - encodedBodySize / decodedBodySize;
132+
if (Number.isFinite(compressionDelta)) {
133+
lux.addData('compressionDelta', compressionDelta);
134+
}
135+
}
136+
69137
// Unattributed Navigation Overhead (UNO): TTFB not covered by named phases.
70138
// https://calendar.perfplanet.com/2024/uno/
71139
const span = (end, start) => Math.max(0, end - start);
@@ -81,7 +149,8 @@
81149
lux.addData('uno', uno);
82150
}
83151

84-
// Time to Last Byte (TTLB)
152+
// Capture the full document response time, beyond the first byte as captured
153+
// by TTFB.
85154
if (navigation.responseEnd && navigation.startTime >= 0) {
86155
const ttlb = Math.round(navigation.responseEnd - navigation.startTime);
87156
if (Number.isFinite(ttlb) && ttlb >= 0) {
@@ -92,7 +161,7 @@
92161
// First Potential Paint (FPP)
93162
const headEnd = performance.getEntriesByName('HEAD_End')[0];
94163

95-
if (headEnd && navigation.startTime >= 0) {
164+
if (navigation && headEnd && navigation.startTime >= 0) {
96165
const fpp = Math.round(headEnd.startTime - navigation.startTime);
97166
if (Number.isFinite(fpp) && fpp >= 0) {
98167
lux.addData('fpp', fpp);

0 commit comments

Comments
 (0)