Skip to content

Commit 55a1cc0

Browse files
authored
Improve type coverage involving network phases (#5539)
This removes some code duplication, and three comments saying `We force-coerce the value into a number just to appease Flow.`
2 parents afc692a + 98ba112 commit 55a1cc0

File tree

6 files changed

+241
-205
lines changed

6 files changed

+241
-205
lines changed

src/components/network-chart/NetworkChartRow.js

Lines changed: 23 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ import {
1313
guessMimeTypeFromNetworkMarker,
1414
getColorClassNameForMimeType,
1515
} from '../../profile-logic/marker-data';
16+
import {
17+
getLatestPreconnectPhaseAndValue,
18+
getMatchingPhaseValues,
19+
} from '../../profile-logic/network';
1620
import { formatNumber } from '../../utils/format-numbers';
1721
import {
1822
TIMELINE_MARGIN_LEFT,
@@ -28,6 +32,7 @@ import type {
2832
Marker,
2933
MarkerIndex,
3034
NetworkPayload,
35+
NetworkPhaseName,
3136
MixedObject,
3237
} from 'firefox-profiler/types';
3338

@@ -65,14 +70,14 @@ const PATH_SPLIT_RE = /(.*)(\/[^/]+\/?)$/;
6570
// `endTime` is the timestamp when the response is delivered to the caller. It's
6671
// not present in this array as it's implicit in the component logic.
6772
// They may be all missing in a specific marker, that's fine.
68-
const PROPERTIES_IN_ORDER = [
73+
const PHASE_NAMES_IN_ORDER: NetworkPhaseName[] = [
6974
'domainLookupStart',
7075
'requestStart',
7176
'responseStart',
7277
'responseEnd',
7378
];
7479

75-
const PHASE_OPACITIES = PROPERTIES_IN_ORDER.reduce(
80+
const PHASE_OPACITIES = PHASE_NAMES_IN_ORDER.reduce(
7681
(result, property, i, { length }) => {
7782
result[property] = length > 1 ? i / (length - 1) : 0;
7883
return result;
@@ -81,8 +86,8 @@ const PHASE_OPACITIES = PROPERTIES_IN_ORDER.reduce(
8186
);
8287

8388
type NetworkPhaseProps = {|
84-
+name: string,
85-
+previousName: string,
89+
+name: NetworkPhaseName,
90+
+previousName: NetworkPhaseName,
8691
+value: number | string,
8792
+duration: Milliseconds,
8893
+style: MixedObject,
@@ -140,25 +145,6 @@ class NetworkChartRowBar extends React.PureComponent<NetworkChartRowBarProps> {
140145
return markerPosition;
141146
}
142147

143-
/**
144-
* Properties `connectEnd` and `domainLookupEnd` aren't always present. This
145-
* function returns the latest one so that we can determine if these phases
146-
* happen in a preconnect session.
147-
*/
148-
_getLatestPreconnectEndProperty(): 'connectEnd' | 'domainLookupEnd' | null {
149-
const { networkPayload } = this.props;
150-
151-
if (typeof networkPayload.connectEnd === 'number') {
152-
return 'connectEnd';
153-
}
154-
155-
if (typeof networkPayload.domainLookupEnd === 'number') {
156-
return 'domainLookupEnd';
157-
}
158-
159-
return null;
160-
}
161-
162148
/**
163149
* This returns the preconnect component, or null if there's no preconnect
164150
* operation for this marker.
@@ -175,15 +161,14 @@ class NetworkChartRowBar extends React.PureComponent<NetworkChartRowBarProps> {
175161
// The preconnect bar goes from the start to the end of the whole preconnect
176162
// operation, that includes both the domain lookup and the connection
177163
// process. Therefore we want the property that represents the latest phase.
178-
const latestPreconnectEndProperty = this._getLatestPreconnectEndProperty();
164+
const latestPreconnectEndProperty = getLatestPreconnectPhaseAndValue(
165+
this.props.networkPayload
166+
);
179167
if (!latestPreconnectEndProperty) {
180168
return null;
181169
}
182170

183-
// We force-coerce the value into a number just to appease Flow. Indeed
184-
// the previous find operation ensures that all values are numbers but
185-
// Flow can't know that.
186-
const preconnectEnd = +networkPayload[latestPreconnectEndProperty];
171+
const preconnectEnd = latestPreconnectEndProperty.value;
187172

188173
// If the latest phase ends before the start of the marker, we'll display a
189174
// separate preconnect bar.
@@ -201,7 +186,7 @@ class NetworkChartRowBar extends React.PureComponent<NetworkChartRowBarProps> {
201186
const preconnectWidth = preconnectEndPosition - preconnectStartPosition;
202187

203188
const preconnectPhase = {
204-
name: latestPreconnectEndProperty,
189+
name: latestPreconnectEndProperty.phase,
205190
previousName: 'domainLookupStart',
206191
value: preconnectEnd,
207192
duration: preconnectDuration,
@@ -243,42 +228,33 @@ class NetworkChartRowBar extends React.PureComponent<NetworkChartRowBarProps> {
243228
const preconnectComponent = this._preconnectComponent();
244229

245230
// Compute the phases for this marker.
246-
247-
// If there's a preconnect phase, we remove `domainLookupStart` from the
248-
// main bar, but we'll draw a separate bar to represent it.
249-
const mainBarProperties = preconnectComponent
250-
? PROPERTIES_IN_ORDER.slice(1)
251-
: PROPERTIES_IN_ORDER;
252-
253-
// Not all properties are always present.
254-
const availableProperties = mainBarProperties.filter(
255-
(property) => typeof networkPayload[property] === 'number'
231+
const availablePhases = getMatchingPhaseValues(
232+
networkPayload,
233+
// If there's a preconnect phase, we remove `domainLookupStart` from the
234+
// main bar, but we'll draw a separate bar to represent it.
235+
preconnectComponent ? PHASE_NAMES_IN_ORDER.slice(1) : PHASE_NAMES_IN_ORDER
256236
);
257237

258238
const mainBarPhases = [];
259239
let previousValue = start;
260240
let previousName = 'startTime';
261241

262242
// In this loop we add the various phases to the array.
263-
availableProperties.forEach((property, i) => {
264-
// We force-coerce the value into a number just to appease Flow. Indeed the
265-
// previous filter ensures that all values are numbers but Flow can't know
266-
// that.
267-
const value = +networkPayload[property];
243+
availablePhases.forEach(({ phase, value }, i) => {
268244
mainBarPhases.push({
269-
name: property,
245+
name: phase,
270246
previousName,
271247
value,
272248
duration: value - previousValue,
273249
style: {
274250
left: ((previousValue - start) / dur) * markerWidth,
275251
width: Math.max(((value - previousValue) / dur) * markerWidth, 1),
276252
// The first phase is always transparent because this represents the wait time.
277-
opacity: i === 0 ? 0 : PHASE_OPACITIES[property],
253+
opacity: i === 0 ? 0 : PHASE_OPACITIES[phase],
278254
},
279255
});
280256
previousValue = value;
281-
previousName = property;
257+
previousName = phase;
282258
});
283259

284260
// The last part isn't generally colored (opacity is 0) unless it's the only

0 commit comments

Comments
 (0)