Skip to content

Commit 73e9e9f

Browse files
Merge pull request #74 from SpeedCurve-Metrics/feature/spa-improvements
Implement "SPA Mode"
2 parents 4860d1f + 9e46a47 commit 73e9e9f

39 files changed

+967
-392
lines changed

docs/debug-parser.html

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,11 @@ <h1>SpeedCurve RUM Debug Parser</h1>
102102
<h2>Parsed debug output <span id="event-counter"></span></h2>
103103

104104
<div class="event-filters">
105-
<label><input type="checkbox" checked class="event-filter" data-event="addData"> LUX.addData()</label>
106-
<label><input type="checkbox" checked class="event-filter" data-event="userTiming"> LUX.mark/measure()</label>
107-
<label><input type="checkbox" class="event-filter" data-event="beaconUrl"> Show beacon URL</label>
105+
<label><input type="checkbox" checked class="event-filter" data-event="metrics"> Metrics Events</label>
106+
<label><input type="checkbox" checked class="event-filter" data-event="addData"> <code>LUX.addData()</code></label>
107+
<label><input type="checkbox" checked class="event-filter" data-event="userTiming"> <code>LUX.mark/measure()</code></label>
108+
<label><input type="checkbox" class="event-filter" data-event="verbose"> Show Verbose Events</label>
109+
<label><input type="checkbox" class="event-filter" data-event="beaconUrl"> Show Beacon URL</label>
108110
</div>
109111

110112
<ul class="mt-1" id="output"></ul>

docs/debug-parser.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/debug-parser/events.ts

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,23 @@ export function isBeaconEvent(event: LogEvent) {
1414
].includes(event);
1515
}
1616

17+
function isVerboseEvent(event: LogEvent) {
18+
return [
19+
LogEvent.DataCollectionStart,
20+
LogEvent.PostBeaconCancelled,
21+
LogEvent.PostBeaconCSPViolation,
22+
LogEvent.PostBeaconInitialised,
23+
LogEvent.PostBeaconSendCalled,
24+
LogEvent.PostBeaconStopRecording,
25+
LogEvent.PostBeaconTimeoutReached,
26+
].includes(event);
27+
}
28+
1729
export function getMessageForEvent(event: LogEventRecord, filters: string[]): string {
30+
if (isVerboseEvent(event[1]) && !filters.includes("verbose")) {
31+
return "";
32+
}
33+
1834
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1935
const args = event[2] as any[];
2036

@@ -26,20 +42,23 @@ export function getMessageForEvent(event: LogEventRecord, filters: string[]): st
2642
}
2743

2844
switch (event[1]) {
29-
case 0:
45+
case 0 as LogEvent:
3046
return "The lux.js script was not loaded on this page.";
3147

3248
case LogEvent.EvaluationStart:
33-
return `lux.js v${args[0]} is initialising.`;
49+
return `lux.js v${args[0]} init begin.`;
3450

3551
case LogEvent.EvaluationEnd:
36-
return "lux.js has finished initialising.";
52+
return "lux.js init complete.";
3753

3854
case LogEvent.InitCalled:
39-
return "LUX.init()";
55+
return "🟢 LUX.init() - new page view started";
56+
57+
case LogEvent.StartSoftNavigationCalled:
58+
return "🟢 LUX.startSoftNavigation() - new page view started";
4059

4160
case LogEvent.MarkLoadTimeCalled:
42-
return `LUX.markLoadTime(${argsAsString(args)})`;
61+
return `🎯 LUX.markLoadTime(${argsAsString(args)})`;
4362

4463
case LogEvent.MarkCalled:
4564
if (filters.includes("userTiming")) {
@@ -71,14 +90,17 @@ export function getMessageForEvent(event: LogEventRecord, filters: string[]): st
7190
case LogEvent.SendCancelledPageHidden:
7291
return "This beacon was not sent because the page visibility was hidden.";
7392

93+
case LogEvent.SendCancelledSpaMode:
94+
return "ℹ️ LUX.send() was ignored because SPA Mode is enabled.";
95+
7496
case LogEvent.ForceSampleCalled:
7597
return "LUX.forceSample()";
7698

7799
case LogEvent.DataCollectionStart:
78100
return "Preparing to send main beacon. Metrics received after this point may be ignored.";
79101

80102
case LogEvent.UnloadHandlerTriggered:
81-
return "Unload handler was triggered.";
103+
return "⤴️ Unload handler was triggered.";
82104

83105
case LogEvent.OnloadHandlerTriggered:
84106
message = `Onload handler was triggered after ${args[0]} ms.`;
@@ -96,7 +118,7 @@ export function getMessageForEvent(event: LogEventRecord, filters: string[]): st
96118
return `Sample rate is ${args[0]}%. This session is not being sampled.`;
97119

98120
case LogEvent.MainBeaconSent:
99-
message = "Main beacon sent";
121+
message = "📫 Main beacon sent";
100122

101123
if (filters.includes("beaconUrl")) {
102124
message += `: ${args[0]}`;
@@ -105,7 +127,7 @@ export function getMessageForEvent(event: LogEventRecord, filters: string[]): st
105127
return message;
106128

107129
case LogEvent.UserTimingBeaconSent:
108-
message = "Supplementary user timing beacon sent";
130+
message = "📧 Supplementary user timing beacon sent";
109131

110132
if (filters.includes("beaconUrl")) {
111133
message += `: ${args[0]}`;
@@ -114,7 +136,7 @@ export function getMessageForEvent(event: LogEventRecord, filters: string[]): st
114136
return message;
115137

116138
case LogEvent.InteractionBeaconSent:
117-
message = "Supplementary user interaction beacon sent";
139+
message = "📧 Supplementary user interaction beacon sent";
118140

119141
if (filters.includes("beaconUrl")) {
120142
message += `: ${args[0]}`;
@@ -123,7 +145,7 @@ export function getMessageForEvent(event: LogEventRecord, filters: string[]): st
123145
return message;
124146

125147
case LogEvent.CustomDataBeaconSent:
126-
message = "Supplementary custom data beacon sent";
148+
message = "📧 Supplementary custom data beacon sent";
127149

128150
if (filters.includes("beaconUrl")) {
129151
message += `: ${args[0]}`;
@@ -142,20 +164,17 @@ export function getMessageForEvent(event: LogEventRecord, filters: string[]): st
142164

143165
case LogEvent.PostBeaconSent:
144166
if (filters.includes("beaconUrl")) {
145-
return `POST beacon sent: ${args[0]}`;
167+
return `📫 POST beacon sent: ${args[0]}`;
146168
}
147169

148-
return "POST beacon sent.";
170+
return "📫 POST beacon sent.";
149171

150172
case LogEvent.PostBeaconSendFailed:
151173
if (filters.includes("beaconUrl")) {
152-
return `POST beacon send failed: ${args[0]}`;
174+
return `⚠️ POST beacon send failed: ${args[0]}`;
153175
}
154176

155-
return "POST beacon send failed.";
156-
157-
case LogEvent.PostBeaconAlreadySent:
158-
return "POST beacon cancelled (already sent).";
177+
return "⚠️ POST beacon send failed.";
159178

160179
case LogEvent.PostBeaconCancelled:
161180
return "POST beacon cancelled.";
@@ -170,12 +189,20 @@ export function getMessageForEvent(event: LogEventRecord, filters: string[]): st
170189
return "POST beacon cancelled due to CSP violation.";
171190

172191
case LogEvent.PostBeaconCollector:
173-
return `POST beacon metric collector: ${args[0]} (has data: ${args[1]})`;
192+
if (filters.includes("metrics")) {
193+
return `POST beacon metric collector: ${args[0]} (has data: ${args[1]})`;
194+
}
195+
196+
return "";
174197

175198
case LogEvent.NavigationStart:
176199
return "";
177200

178201
case LogEvent.PerformanceEntryReceived:
202+
if (!filters.includes("metrics")) {
203+
return "";
204+
}
205+
179206
if (args[0].entryType === "layout-shift") {
180207
return `Received layout shift at ${args[0].startTime.toFixed()} ms with value of ${args[0].value.toFixed(
181208
3,
@@ -207,7 +234,7 @@ export function getMessageForEvent(event: LogEventRecord, filters: string[]): st
207234
return message;
208235

209236
case LogEvent.PerformanceEntryProcessed:
210-
if (args[0].entryType === "largest-contentful-paint") {
237+
if (filters.includes("metrics") && args[0].entryType === "largest-contentful-paint") {
211238
return `Picked LCP from entry at ${args[0].startTime.toFixed()} ms`;
212239
}
213240

@@ -272,6 +299,12 @@ function getEventName(event: LogEvent) {
272299
return "MarkLoadTimeCalled";
273300
case LogEvent.SendCancelledPageHidden:
274301
return "SendCancelledPageHidden";
302+
case LogEvent.StartSoftNavigationCalled:
303+
return "StartSoftNavigationCalled";
304+
case LogEvent.SendCancelledSpaMode:
305+
return "SendCancelledSpaMode";
306+
case LogEvent.BfCacheRestore:
307+
return "BfCacheRestore";
275308
case LogEvent.SessionIsSampled:
276309
return "SessionIsSampled";
277310
case LogEvent.SessionIsNotSampled:
@@ -318,8 +351,6 @@ function getEventName(event: LogEvent) {
318351
return "PostBeaconTimeoutReached";
319352
case LogEvent.PostBeaconSent:
320353
return "PostBeaconSent";
321-
case LogEvent.PostBeaconAlreadySent:
322-
return "PostBeaconAlreadySent";
323354
case LogEvent.PostBeaconCancelled:
324355
return "PostBeaconCancelled";
325356
case LogEvent.PostBeaconStopRecording:
@@ -333,4 +364,6 @@ function getEventName(event: LogEvent) {
333364
case LogEvent.PostBeaconCollector:
334365
return "PostBeaconCollector";
335366
}
367+
368+
return "Unknown Event";
336369
}

docs/debug-parser/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ function renderOutput(output: Element) {
3434
output.appendChild(li(`Could not parse input: ${err}`, "red"));
3535
}
3636

37-
eventCounter.innerText = `(${inputEvents.length} events)`;
37+
const sentBeacons = inputEvents.filter((event) => event[1] === LogEvent.MainBeaconSent);
38+
39+
eventCounter.innerText = `(${inputEvents.length} events; ${sentBeacons.length} page views)`;
3840

3941
let navigationStart = Number(new Date(inputEvents[0][0]));
4042

@@ -183,7 +185,7 @@ function renderOutput(output: Element) {
183185

184186
output.prepend(
185187
li(
186-
`0 ms: Navigation started at ${startTime.toLocaleDateString()} ${startTime.toLocaleTimeString()}`,
188+
`0 ms: 🟢 Navigation started at ${startTime.toLocaleDateString()} ${startTime.toLocaleTimeString()}`,
187189
),
188190
);
189191
}

docs/examples.md

Whitespace-only changes.

docs/spa-mode.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPA Mode in lux.js
2+
3+
## Migrating from `LUX.auto = false`
4+
5+
- Remove `LUX.auto = false`.
6+
- Remove all `LUX.send()` calls. In SPA mode, the beacon is sent automatically. In some very rare cases you may want to send the beacon manually, which can be done by calling `LUX.send(true)` - **this is not recommended**.
7+
- Replace all `LUX.init()` calls with `LUX.startSoftNavigation()`.

docs/usage-changes.md

Lines changed: 0 additions & 158 deletions
This file was deleted.

0 commit comments

Comments
 (0)