Skip to content

Commit 5aefb07

Browse files
committed
Continuity: Fix TTFI when EventTiming plugin is missing
1 parent f0a6649 commit 5aefb07

File tree

3 files changed

+120
-6
lines changed

3 files changed

+120
-6
lines changed

plugins/continuity.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3835,7 +3835,7 @@
38353835
* Analyzes Interactions
38363836
*/
38373837
function analyze(startTime) {
3838-
var fid;
3838+
var fid, ttfi, ET;
38393839

38403840
impl.addToBeacon("c.i.dc", externalMetrics.interactionDelayed());
38413841
impl.addToBeacon("c.i.dt", externalMetrics.interactionDelayedTime());
@@ -3844,20 +3844,25 @@
38443844
// Only send FID and TTFI Timers once
38453845
if (!sentTimers) {
38463846
// defer to EventTiming's FID if available
3847-
if (BOOMR.plugins.EventTiming &&
3848-
BOOMR.plugins.EventTiming.is_enabled()) {
3849-
fid = BOOMR.plugins.EventTiming.metrics.firstInputDelay();
3847+
ET = BOOMR.plugins.EventTiming;
3848+
3849+
if (ET && ET.is_enabled()) {
3850+
fid = ET.metrics.firstInputDelay();
3851+
ttfi = ET.metrics.timeToFirstInteraction();
38503852
}
38513853

38523854
if (!fid && firstInputDelay !== null) {
38533855
fid = externalMetrics.firstInputDelay();
38543856
}
38553857

3858+
if (!ttfi) {
3859+
ttfi = externalMetrics.timeToFirstInteraction();
3860+
}
3861+
38563862
if (typeof fid === "number") {
38573863
impl.addToBeacon("c.fid", Math.ceil(fid), true);
38583864

3859-
impl.addToBeacon("c.ttfi",
3860-
BOOMR.plugins.EventTiming.metrics.timeToFirstInteraction() || externalMetrics.timeToFirstInteraction());
3865+
impl.addToBeacon("c.ttfi", ttfi, true);
38613866

38623867
sentTimers = true;
38633868
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<%= header %>
2+
<!--
3+
Same as 13-interaction but without the EventTiming plugin
4+
-->
5+
<%= boomerangScript %>
6+
<p>45-interaction-no-eventtiming loading...</p>
7+
<script src="49-interaction-no-eventtiming.js" type="text/javascript"></script>
8+
<script>
9+
// test that `c.ttfi` can be set without the EventTiming plugin
10+
delete BOOMR.plugins.EventTiming;
11+
12+
BOOMR_test.init({
13+
testAfterOnBeacon: true,
14+
Continuity: {
15+
enabled: true
16+
}
17+
});
18+
19+
try {
20+
// the event timestamp is set when the object is created
21+
var ev = document.createEvent("Event");
22+
23+
ev.initEvent("keydown", true, true);
24+
ev.keyCode = 27;
25+
}
26+
catch (e) {
27+
window.cannotCreateMouseEvent = true;
28+
}
29+
30+
// click
31+
window.ttfi = BOOMR.now();
32+
33+
// dispatch event is synchronous. Wait 20ms between the event creation and dispatch
34+
BOOMR_test.busy(20);
35+
document.dispatchEvent(ev);
36+
37+
setTimeout(function() {
38+
// click key again
39+
document.dispatchEvent(ev);
40+
document.dispatchEvent(ev);
41+
}, 250);
42+
</script>
43+
<img src="/delay?delay=3000&amp;file=assets/img.jpg" width="200" height="10000" />
44+
<%= footer %>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* eslint-env mocha */
2+
/* global BOOMR_test,assert */
3+
4+
describe("e2e/21-continuity/49-interaction-no-eventtiming", function() {
5+
var tf = BOOMR.plugins.TestFramework;
6+
var t = BOOMR_test;
7+
8+
it("Should have sent a single beacon validation", function(done) {
9+
t.validateBeaconWasSent(done);
10+
});
11+
12+
it("Should not have the EventTiming plugin", function(done) {
13+
assert.isUndefined(BOOMR.plugins.EventTiming);
14+
});
15+
16+
it("Should have sent the Time to First Interaction (c.ttfi)", function() {
17+
var b = tf.lastBeacon();
18+
19+
assert.isDefined(b["c.ttfi"]);
20+
var ttfi = parseInt(b["c.ttfi"], 10);
21+
22+
if (t.isNavigationTimingSupported()) {
23+
var st = parseInt(b["rt.tstart"], 10);
24+
25+
assert.closeTo(st + ttfi, window.ttfi, 20);
26+
}
27+
else {
28+
assert.operator(ttfi, ">=", 0);
29+
}
30+
});
31+
32+
it("Should have the interaction timeline (c.t.inter)", function() {
33+
var b = tf.lastBeacon();
34+
35+
assert.isDefined(b["c.t.inter"]);
36+
assert.operator(b["c.t.inter"].length, ">=", 1);
37+
});
38+
39+
it("Could have the interaction delay timeline (c.t.interdly)", function() {
40+
var b = tf.lastBeacon();
41+
42+
if (b["c.i.a"]) {
43+
assert.isDefined(b["c.t.interdly"]);
44+
assert.operator(b["c.t.interdly"].length, ">=", 1);
45+
}
46+
});
47+
48+
it("Could have interaction delay metrics (c.i.a, c.i.dc and c.i.dt)", function() {
49+
var b = tf.lastBeacon();
50+
51+
if (!b["c.i.a"]) {
52+
assert.operator(parseInt(b["c.i.a"], 10), ">=", 1);
53+
assert.operator(parseInt(b["c.i.dc"], 10), ">=", 1);
54+
assert.operator(parseInt(b["c.i.dc"], 10), "<=", 10);
55+
assert.operator(parseInt(b["c.i.dt"], 10), ">=", 1);
56+
}
57+
});
58+
59+
it("Should have First Input Delay (c.fid)", function() {
60+
var b = tf.lastBeacon();
61+
62+
assert.isDefined(b["c.fid"]);
63+
assert.operator(parseInt(b["c.fid"], 10), ">=", 19); // we had a 20ms busy wait, allow for some fuzzing
64+
});
65+
});

0 commit comments

Comments
 (0)