Skip to content

Commit a44a7a2

Browse files
author
Brian Vaughn
authored
Filter empty commits (all Fibers bailed out) from Profiler (#22745)
1 parent e0aa5e2 commit a44a7a2

File tree

4 files changed

+86
-208
lines changed

4 files changed

+86
-208
lines changed

packages/react-devtools-shared/src/__tests__/__snapshots__/profilingCache-test.js.snap

-197
Original file line numberDiff line numberDiff line change
@@ -1700,94 +1700,6 @@ Object {
17001700
}
17011701
`;
17021702

1703-
exports[`ProfilingCache should collect data for each root (including ones added or mounted after profiling started): Data for root Parent 3`] = `
1704-
Object {
1705-
"commitData": Array [
1706-
Object {
1707-
"changeDescriptions": Map {},
1708-
"duration": 0,
1709-
"effectDuration": 0,
1710-
"fiberActualDurations": Map {},
1711-
"fiberSelfDurations": Map {},
1712-
"passiveEffectDuration": 0,
1713-
"priorityLevel": "Immediate",
1714-
"timestamp": 34,
1715-
"updaters": Array [
1716-
Object {
1717-
"displayName": "render()",
1718-
"hocDisplayNames": null,
1719-
"id": 7,
1720-
"key": null,
1721-
"type": 11,
1722-
},
1723-
],
1724-
},
1725-
],
1726-
"displayName": "Parent",
1727-
"initialTreeBaseDurations": Map {
1728-
7 => 11,
1729-
8 => 11,
1730-
10 => 0,
1731-
11 => 1,
1732-
},
1733-
"operations": Array [
1734-
Array [
1735-
1,
1736-
7,
1737-
0,
1738-
2,
1739-
4,
1740-
11,
1741-
10,
1742-
8,
1743-
7,
1744-
],
1745-
],
1746-
"rootID": 7,
1747-
"snapshots": Map {
1748-
7 => Object {
1749-
"children": Array [
1750-
8,
1751-
],
1752-
"displayName": null,
1753-
"hocDisplayNames": null,
1754-
"id": 7,
1755-
"key": null,
1756-
"type": 11,
1757-
},
1758-
8 => Object {
1759-
"children": Array [
1760-
10,
1761-
11,
1762-
],
1763-
"displayName": "Parent",
1764-
"hocDisplayNames": null,
1765-
"id": 8,
1766-
"key": null,
1767-
"type": 5,
1768-
},
1769-
10 => Object {
1770-
"children": Array [],
1771-
"displayName": "Child",
1772-
"hocDisplayNames": null,
1773-
"id": 10,
1774-
"key": "0",
1775-
"type": 5,
1776-
},
1777-
11 => Object {
1778-
"children": Array [],
1779-
"displayName": "Child",
1780-
"hocDisplayNames": Array [
1781-
"Memo",
1782-
],
1783-
"id": 11,
1784-
"key": null,
1785-
"type": 8,
1786-
},
1787-
},
1788-
}
1789-
`;
1790-
17911703
exports[`ProfilingCache should collect data for each root (including ones added or mounted after profiling started): imported data 1`] = `
17921704
Object {
17931705
"dataForRoots": Array [
@@ -2330,115 +2242,6 @@ Object {
23302242
"rootID": 13,
23312243
"snapshots": Array [],
23322244
},
2333-
Object {
2334-
"commitData": Array [
2335-
Object {
2336-
"changeDescriptions": Array [],
2337-
"duration": 0,
2338-
"effectDuration": 0,
2339-
"fiberActualDurations": Array [],
2340-
"fiberSelfDurations": Array [],
2341-
"passiveEffectDuration": 0,
2342-
"priorityLevel": "Immediate",
2343-
"timestamp": 34,
2344-
"updaters": Array [
2345-
Object {
2346-
"displayName": "render()",
2347-
"hocDisplayNames": null,
2348-
"id": 7,
2349-
"key": null,
2350-
"type": 11,
2351-
},
2352-
],
2353-
},
2354-
],
2355-
"displayName": "Parent",
2356-
"initialTreeBaseDurations": Array [
2357-
Array [
2358-
7,
2359-
11,
2360-
],
2361-
Array [
2362-
8,
2363-
11,
2364-
],
2365-
Array [
2366-
10,
2367-
0,
2368-
],
2369-
Array [
2370-
11,
2371-
1,
2372-
],
2373-
],
2374-
"operations": Array [
2375-
Array [
2376-
1,
2377-
7,
2378-
0,
2379-
2,
2380-
4,
2381-
11,
2382-
10,
2383-
8,
2384-
7,
2385-
],
2386-
],
2387-
"rootID": 7,
2388-
"snapshots": Array [
2389-
Array [
2390-
7,
2391-
Object {
2392-
"children": Array [
2393-
8,
2394-
],
2395-
"displayName": null,
2396-
"hocDisplayNames": null,
2397-
"id": 7,
2398-
"key": null,
2399-
"type": 11,
2400-
},
2401-
],
2402-
Array [
2403-
8,
2404-
Object {
2405-
"children": Array [
2406-
10,
2407-
11,
2408-
],
2409-
"displayName": "Parent",
2410-
"hocDisplayNames": null,
2411-
"id": 8,
2412-
"key": null,
2413-
"type": 5,
2414-
},
2415-
],
2416-
Array [
2417-
10,
2418-
Object {
2419-
"children": Array [],
2420-
"displayName": "Child",
2421-
"hocDisplayNames": null,
2422-
"id": 10,
2423-
"key": "0",
2424-
"type": 5,
2425-
},
2426-
],
2427-
Array [
2428-
11,
2429-
Object {
2430-
"children": Array [],
2431-
"displayName": "Child",
2432-
"hocDisplayNames": Array [
2433-
"Memo",
2434-
],
2435-
"id": 11,
2436-
"key": null,
2437-
"type": 8,
2438-
},
2439-
],
2440-
],
2441-
},
24422245
],
24432246
"version": 5,
24442247
}

packages/react-devtools-shared/src/__tests__/profilerStore-test.js

+51
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,57 @@ describe('ProfilerStore', () => {
124124
expect(data.operations).toHaveLength(1);
125125
});
126126

127+
it('should filter empty commits alt', () => {
128+
let commitCount = 0;
129+
130+
const inputRef = React.createRef();
131+
const Example = () => {
132+
const [, setTouched] = React.useState(false);
133+
134+
const handleBlur = () => {
135+
setTouched(true);
136+
};
137+
138+
require('scheduler').unstable_advanceTime(1);
139+
140+
React.useLayoutEffect(() => {
141+
commitCount++;
142+
});
143+
144+
return <input ref={inputRef} onBlur={handleBlur} />;
145+
};
146+
147+
const container = document.createElement('div');
148+
149+
// This element has to be in the <body> for the event system to work.
150+
document.body.appendChild(container);
151+
152+
// It's important that this test uses legacy sync mode.
153+
// The root API does not trigger this particular failing case.
154+
legacyRender(<Example />, container);
155+
156+
expect(commitCount).toBe(1);
157+
commitCount = 0;
158+
159+
utils.act(() => store.profilerStore.startProfiling());
160+
161+
// Focus and blur.
162+
const target = inputRef.current;
163+
target.focus();
164+
target.blur();
165+
target.focus();
166+
target.blur();
167+
expect(commitCount).toBe(1);
168+
169+
utils.act(() => store.profilerStore.stopProfiling());
170+
171+
// Only one commit should have been recorded (in response to the "change" event).
172+
const root = store.roots[0];
173+
const data = store.profilerStore.getDataForRoot(root);
174+
expect(data.commitData).toHaveLength(1);
175+
expect(data.operations).toHaveLength(1);
176+
});
177+
127178
it('should throw if component filters are modified while profiling', () => {
128179
utils.act(() => store.profilerStore.startProfiling());
129180

packages/react-devtools-shared/src/__tests__/profilingCache-test.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,10 @@ describe('ProfilingCache', () => {
108108
});
109109
}
110110

111-
expect(allProfilingDataForRoots).toHaveLength(3);
111+
// No profiling data gets logged for the 2nd root (container B)
112+
// because it doesn't render anything while profiling.
113+
// (Technically it unmounts but we don't profile root unmounts.)
114+
expect(allProfilingDataForRoots).toHaveLength(2);
112115

113116
utils.exportImportHelper(bridge, store);
114117

packages/react-devtools-shared/src/backend/renderer.js

+31-10
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,19 @@ export function attach(
15461546
}
15471547

15481548
function flushOrQueueOperations(operations: OperationsArray): void {
1549+
if (operations.length === 3) {
1550+
// This operations array is a no op: [renderer ID, root ID, string table size (0)]
1551+
// We can usually skip sending updates like this across the bridge, unless we're Profiling.
1552+
// In that case, even though the tree didn't change– some Fibers may have still rendered.
1553+
if (
1554+
!isProfiling ||
1555+
currentCommitProfilingMetadata == null ||
1556+
currentCommitProfilingMetadata.durations.length === 0
1557+
) {
1558+
return;
1559+
}
1560+
}
1561+
15491562
if (pendingOperationsQueue !== null) {
15501563
pendingOperationsQueue.push(operations);
15511564
} else {
@@ -2608,18 +2621,26 @@ export function attach(
26082621
}
26092622

26102623
if (isProfiling && isProfilingSupported) {
2611-
const commitProfilingMetadata = ((rootToCommitProfilingMetadataMap: any): CommitProfilingMetadataMap).get(
2612-
currentRootID,
2613-
);
2614-
if (commitProfilingMetadata != null) {
2615-
commitProfilingMetadata.push(
2616-
((currentCommitProfilingMetadata: any): CommitProfilingData),
2617-
);
2618-
} else {
2619-
((rootToCommitProfilingMetadataMap: any): CommitProfilingMetadataMap).set(
2624+
// Make sure at least one Fiber performed work during this commit.
2625+
// If not, don't send it to the frontend; showing an empty commit in the Profiler is confusing.
2626+
if (
2627+
currentCommitProfilingMetadata != null &&
2628+
currentCommitProfilingMetadata.durations.length > 0
2629+
) {
2630+
const commitProfilingMetadata = ((rootToCommitProfilingMetadataMap: any): CommitProfilingMetadataMap).get(
26202631
currentRootID,
2621-
[((currentCommitProfilingMetadata: any): CommitProfilingData)],
26222632
);
2633+
2634+
if (commitProfilingMetadata != null) {
2635+
commitProfilingMetadata.push(
2636+
((currentCommitProfilingMetadata: any): CommitProfilingData),
2637+
);
2638+
} else {
2639+
((rootToCommitProfilingMetadataMap: any): CommitProfilingMetadataMap).set(
2640+
currentRootID,
2641+
[((currentCommitProfilingMetadata: any): CommitProfilingData)],
2642+
);
2643+
}
26232644
}
26242645
}
26252646

0 commit comments

Comments
 (0)