Skip to content

Commit 90e3af2

Browse files
dschomvbudhram
authored andcommitted
fix(content): Another metrics fix
Because: - Our API expects integer values for all timing related metrics, but chrome can produce floats. This Commit: - Ensures that all timing metrics coming from speed strap are integers.
1 parent 6cac315 commit 90e3af2

3 files changed

Lines changed: 50 additions & 38 deletions

File tree

packages/fxa-shared/speed-trap/events.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@ class Events {
77
this.events = [];
88

99
if (!options || !options.performance) {
10-
throw new Error('options.performance is required!')
10+
throw new Error('options.performance is required!');
1111
}
1212
this.performance = options.performance;
1313
}
1414

1515
capture(name) {
1616
this.events.push({
1717
type: name,
18-
offset: this.performance.now(),
18+
19+
// Chrome produces floats, but our API expects integers
20+
offset: parseInt(this.performance.now()),
1921
});
2022
}
2123

packages/fxa-shared/speed-trap/navigation-timing.js

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,48 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
import {NAVIGATION_TIMING_FIELDS, OPTIONAL_NAVIGATION_TIMING_FIELDS} from './timing-fields';
5+
import {
6+
NAVIGATION_TIMING_FIELDS,
7+
OPTIONAL_NAVIGATION_TIMING_FIELDS,
8+
} from './timing-fields';
69

710
const L2TimingsMap = {
8-
'navigationStart': 'startTime',
9-
'domLoading': 'domContentLoadedEventStart'
10-
}
11+
navigationStart: 'startTime',
12+
domLoading: 'domContentLoadedEventStart',
13+
};
1114

1215
const TimingVersions = {
1316
L2: 'L2',
1417
L1: 'L1',
15-
UNKNOWN: ''
16-
}
18+
UNKNOWN: '',
19+
};
1720

1821
class NavigationTiming {
1922
init(opts) {
20-
2123
// A performance api must be provided
2224
if (!opts || !opts.performance) {
23-
throw new Error('opts.performance is required!')
25+
throw new Error('opts.performance is required!');
2426
}
2527
this.performance = opts.performance;
2628
this.useL1Timings = opts.useL1Timings;
2729
}
2830

29-
getTimingVersion () {
30-
const version = this.getL2Timings() ? TimingVersions.L2 :
31-
this.getL1Timings() ? TimingVersions.L1 :
32-
TimingVersions.UNKNOWN;
31+
getTimingVersion() {
32+
const version = this.getL2Timings()
33+
? TimingVersions.L2
34+
: this.getL1Timings()
35+
? TimingVersions.L1
36+
: TimingVersions.UNKNOWN;
3337
return version;
3438
}
3539

3640
getL2Timings() {
3741
if (
3842
!!this.performance &&
3943
!!this.performance.getEntriesByType &&
40-
!!this.performance.getEntriesByType('navigation'))
41-
{
42-
return this.performance.getEntriesByType('navigation')[0]
44+
!!this.performance.getEntriesByType('navigation')
45+
) {
46+
return this.performance.getEntriesByType('navigation')[0];
4347
}
4448
}
4549

@@ -48,14 +52,13 @@ class NavigationTiming {
4852
}
4953

5054
diff() {
51-
5255
// If we are using our fallback performance api (ie window.performance
5356
// doesn't exist), don't return anything.
5457
if (this.performance.unreliable === true) {
5558
return undefined;
5659
}
5760

58-
const diff = {}
61+
const diff = {};
5962
const l2Timings = this.getL2Timings();
6063
const l1Timings = this.getL1Timings();
6164

@@ -64,11 +67,13 @@ class NavigationTiming {
6467
for (const key in NAVIGATION_TIMING_FIELDS) {
6568
const timing = l1Timings[key];
6669

67-
if (timing === 0 && OPTIONAL_NAVIGATION_TIMING_FIELDS.indexOf(key) >= 0) {
70+
if (
71+
timing === 0 &&
72+
OPTIONAL_NAVIGATION_TIMING_FIELDS.indexOf(key) >= 0
73+
) {
6874
// A time value of 0 for certain fields indicates a non-applicable value. Set to null.
6975
diff[key] = null;
70-
}
71-
else {
76+
} else {
7277
// Compute the delta relative to navigation start. This removes any
7378
// ambiguity around what the 'start' or 'baseTime' time is. Since we
7479
// are sure the current set of navigation timings were created using
@@ -78,7 +83,7 @@ class NavigationTiming {
7883
}
7984
}
8085

81-
function diffL2 () {
86+
function diffL2() {
8287
// If we have level 2 timings we can almost return the timings directly. We just have massage
8388
// a couple fields to keep it backwards compatible.
8489
for (const key in NAVIGATION_TIMING_FIELDS) {
@@ -90,18 +95,22 @@ class NavigationTiming {
9095
// Case for testing. We should always try to use l2, but if explicitly requested use L1.
9196
if (this.useL1Timings && l1Timings) {
9297
diffL1();
93-
}
94-
else if (l2Timings) {
98+
} else if (l2Timings) {
9599
diffL2();
96-
}
97-
else if (l1Timings) {
100+
} else if (l1Timings) {
98101
diffL1();
99102
}
100103

101-
// We shouldn't see any negative values. If we do something went very wrong.
102-
// We will use -11111 as a magic number to ensure a sentry error is captured,
103-
// and it's easy to spot.
104104
for (const key in NAVIGATION_TIMING_FIELDS) {
105+
// We expect that all values are integer values, Chrome will produce floating
106+
// point values that we must convert.
107+
if (typeof diff[key] === 'number') {
108+
diff[key] = parseInt(diff[key]);
109+
}
110+
111+
// We shouldn't see any negative values. If we do something went very wrong.
112+
// We will use -11111 as a magic number to ensure a sentry error is captured,
113+
// and it's easy to spot.
105114
if (diff[key] < 0) {
106115
diff[key] = -11111;
107116
}

packages/fxa-shared/speed-trap/speed-trap.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,19 @@ var SpeedTrap = {
1515
// reduced functionality. The exact performance API can also be passed in as option
1616
// for testing purposes.
1717
this.performance = options.performance || getPerformanceApi();
18-
this.baseTime = this.performance.timeOrigin;
18+
this.baseTime = parseInt(this.performance.timeOrigin);
1919

2020
this.navigationTiming = Object.create(NavigationTiming);
2121
this.navigationTiming.init({
2222
performance: this.performance,
23-
useL1Timings: options.useL1Timings
23+
useL1Timings: options.useL1Timings,
2424
});
2525

2626
this.timers = Object.create(Timers);
27-
this.timers.init({performance: this.performance});
27+
this.timers.init({ performance: this.performance });
2828

2929
this.events = Object.create(Events);
30-
this.events.init({performance: this.performance});
30+
this.events.init({ performance: this.performance });
3131

3232
this.uuid = guid();
3333

@@ -106,7 +106,7 @@ var SpeedTrap = {
106106
// performance.timeOrigin or performance.timings.navigationStart and get a valid value.
107107
// It's very likely the performance API is using a monotonic clock that does not match our
108108
// current system clock.
109-
duration: this.performance.now(),
109+
duration: parseInt(this.performance.now()),
110110
timers: this.timers.get(),
111111
events: this.events.get(),
112112
};
@@ -122,8 +122,9 @@ var SpeedTrap = {
122122
* Note: performance.now() will likely differ from Date.now() and is not expected to be the real
123123
* time. Please be aware of what underlying implementation is in use when calling this function.
124124
*/
125-
now: function() {
126-
return this.performance.timeOrigin + this.performance.now();
125+
now: function () {
126+
// Chrome's performance api returns floats, but our API requires integers.
127+
return parseInt(this.performance.timeOrigin + this.performance.now());
127128
},
128129

129130
/**
@@ -135,7 +136,7 @@ var SpeedTrap = {
135136
return this.performance.isInSuspectState();
136137
}
137138
return false;
138-
}
139+
},
139140
};
140141

141142
export default Object.create(SpeedTrap);

0 commit comments

Comments
 (0)