diff --git a/src/components/tooltip/NetworkMarker.tsx b/src/components/tooltip/NetworkMarker.tsx
index c7f231c6c3..91c9a4b329 100644
--- a/src/components/tooltip/NetworkMarker.tsx
+++ b/src/components/tooltip/NetworkMarker.tsx
@@ -338,6 +338,22 @@ export function getNetworkMarkerDetails(
);
}
+ if (payload.secPurpose) {
+ details.push(
+
+ {payload.secPurpose}
+
+ );
+ }
+
+ if (payload.deliveryType) {
+ details.push(
+
+ {payload.deliveryType}
+
+ );
+ }
+
if (typeof payload.count === 'number') {
details.push(
diff --git a/src/profile-logic/marker-schema.ts b/src/profile-logic/marker-schema.ts
index 59454a280d..5383bdee19 100644
--- a/src/profile-logic/marker-schema.ts
+++ b/src/profile-logic/marker-schema.ts
@@ -83,6 +83,18 @@ export const markerSchemaFrontEndOnly: MarkerSchema[] = [
label: 'Response Status',
hidden: true,
},
+ {
+ format: 'string',
+ key: 'secPurpose',
+ label: 'Sec-Purpose',
+ hidden: true,
+ },
+ {
+ format: 'string',
+ key: 'deliveryType',
+ label: 'Delivery Type',
+ hidden: true,
+ },
],
},
];
diff --git a/src/test/components/NetworkChart.test.tsx b/src/test/components/NetworkChart.test.tsx
index df129b0c15..ba71ab9d91 100644
--- a/src/test/components/NetworkChart.test.tsx
+++ b/src/test/components/NetworkChart.test.tsx
@@ -622,6 +622,62 @@ describe('NetworkChartRowBar MIME-type filter', function () {
});
});
+describe('Network chart prefetch search', function () {
+ // The fields are hidden in the schema, so they never render in the chart;
+ // they exist so a search for "prefetch" narrows to just these requests.
+ function setup() {
+ return setupWithPayload([
+ ...getNetworkMarkers({ uri: 'https://mozilla.org/plain', id: 1 }),
+ ...getNetworkMarkers({
+ uri: 'https://mozilla.org/speculative',
+ id: 2,
+ payload: { secPurpose: 'prefetch' },
+ }),
+ ...getNetworkMarkers({
+ uri: 'https://mozilla.org/activated',
+ id: 3,
+ payload: { deliveryType: 'navigational-prefetch' },
+ }),
+ ]);
+ }
+
+ function visibleUrls(container: HTMLElement) {
+ return Array.from(
+ container.querySelectorAll('.networkChartRowItemLabel')
+ ).map((node) => node.textContent);
+ }
+
+ it('shows every request when not searching', function () {
+ const { container } = setup();
+ expect(visibleUrls(container)).toHaveLength(3);
+ });
+
+ it('narrows to prefetches when searching for "prefetch"', function () {
+ const { container, dispatch } = setup();
+
+ act(() => {
+ dispatch(changeNetworkSearchString('prefetch'));
+ });
+
+ const urls = visibleUrls(container);
+ expect(urls).toHaveLength(2);
+ expect(urls.join(' ')).toContain('/speculative');
+ expect(urls.join(' ')).toContain('/activated');
+ });
+
+ it('narrows to the activated navigation alone', function () {
+ const { container, dispatch } = setup();
+
+ act(() => {
+ dispatch(changeNetworkSearchString('navigational-prefetch'));
+ });
+
+ const urls = visibleUrls(container);
+ expect(urls).toHaveLength(1);
+ expect(urls[0]).toContain('/activated');
+ });
+});
+
describe('EmptyReasons', () => {
it("shows a reason when a profile's network markers have been filtered out", () => {
const { dispatch, container } = setupWithPayload([...NETWORK_MARKERS]);
diff --git a/src/test/components/TooltipMarker.test.tsx b/src/test/components/TooltipMarker.test.tsx
index 938a5bc361..c80c87ae87 100644
--- a/src/test/components/TooltipMarker.test.tsx
+++ b/src/test/components/TooltipMarker.test.tsx
@@ -686,6 +686,30 @@ describe('TooltipMarker', function () {
expect(container.firstChild).toMatchSnapshot();
});
+ it('renders the Sec-Purpose of a prefetched request', () => {
+ setupWithPayload(
+ getNetworkMarkers({
+ uri: 'https://example.org/next-page.html',
+ payload: { secPurpose: 'prefetch;anonymous-client-ip' },
+ })
+ );
+
+ expect(getValueForProperty('Sec-Purpose')).toBe(
+ 'prefetch;anonymous-client-ip'
+ );
+ });
+
+ it('renders the delivery type of a navigation served from a prefetch', () => {
+ setupWithPayload(
+ getNetworkMarkers({
+ uri: 'https://example.org/next-page.html',
+ payload: { deliveryType: 'navigational-prefetch' },
+ })
+ );
+
+ expect(getValueForProperty('Delivery Type')).toBe('navigational-prefetch');
+ });
+
it('renders the page information for network markers', () => {
setupWithPayload(
getNetworkMarkers({
diff --git a/src/types/markers.ts b/src/types/markers.ts
index e3eb9217b5..f60d98dfdd 100644
--- a/src/types/markers.ts
+++ b/src/types/markers.ts
@@ -556,6 +556,15 @@ export type NetworkPayload = {
// Used to show the HTTP response status code
responseStatus?: number;
+ // The `Sec-Purpose` request header, only present for prefetches.
+ // It's always absent in Firefox < 155.
+ secPurpose?: string;
+
+ // Matches PerformanceNavigationTiming's deliveryType. Only present when the
+ // navigation was served from a prefetch, as "navigational-prefetch".
+ // It's always absent in Firefox < 155.
+ deliveryType?: string;
+
// NOTE: the following comments are valid for the merged markers. For the raw
// markers, startTime and endTime have different meanings. Please look
// `src/profile-logic/marker-data.js` for more information.