Profiler: Skip reading element for imported data (#18913)
* skip reading element for imported data * rename nodes & enable store lookup for components tab * replace names * Added some more test coverage; reverted rename Co-authored-by: Brian Vaughn <bvaughn@fb.com>
Nick Reiley committed
May 15, 2020 at 22:38 UTC
dd2e36df33194ddd37844507dc6a88e0906df516
5 files changed
+20
-19
packages/react-devtools-shared/src/__tests__/profilerContext-test.js
-8
@@ -337,18 +337,10 @@ describe('ProfilerContext', () => {
337
await utils.actAsync(() => context.selectFiber(parentID, 'Parent'));
338
expect(selectedElementID).toBe(parentID);
339
340
- // We expect a "no element found" warning.
341
- // Let's hide it from the test console though.
342
- spyOn(console, 'warn');
343
-
340
// Select an unmounted element and verify no Components tab selection doesn't change.
341
await utils.actAsync(() => context.selectFiber(childID, 'Child'));
342
expect(selectedElementID).toBe(parentID);
343
348
- expect(console.warn).toHaveBeenCalledWith(
349
- `No element found with id "${childID}"`,
350
- );
351
-
344
done();
345
});
346
});
packages/react-devtools-shared/src/__tests__/utils.js
+6
-2
@@ -181,6 +181,7 @@ export function exportImportHelper(bridge: FrontendBridge, store: Store): void {
181
expect(profilerStore.profilingData).not.toBeNull();
182
183
const profilingDataFrontendInitial = ((profilerStore.profilingData: any): ProfilingDataFrontend);
184
+ expect(profilingDataFrontendInitial.imported).toBe(false);
185
186
const profilingDataExport = prepareProfilingDataExport(
187
profilingDataFrontendInitial,
@@ -197,15 +198,18 @@ export function exportImportHelper(bridge: FrontendBridge, store: Store): void {
198
const profilingDataFrontend = prepareProfilingDataFrontendFromExport(
199
(parsedProfilingDataExport: any),
200
);
201
+ expect(profilingDataFrontend.imported).toBe(true);
202
203
// Sanity check that profiling snapshots are serialized correctly.
202
- expect(profilingDataFrontendInitial).toEqual(profilingDataFrontend);
204
+ expect(profilingDataFrontendInitial.dataForRoots).toEqual(
205
+ profilingDataFrontend.dataForRoots,
206
+ );
207
208
// Snapshot the JSON-parsed object, rather than the raw string, because Jest formats the diff nicer.
209
expect(parsedProfilingDataExport).toMatchSnapshot('imported data');
210
211
act(() => {
208
- // Apply the new exported-then-reimported data so tests can re-run assertions.
212
+ // Apply the new exported-then-imported data so tests can re-run assertions.
213
profilerStore.profilingData = profilingDataFrontend;
214
});
215
}
packages/react-devtools-shared/src/devtools/views/Profiler/ProfilerContext.js
+11
-7
@@ -138,12 +138,16 @@ function ProfilerContextController({children}: Props) {
138
selectFiberName(name);
139
140
// Sync selection to the Components tab for convenience.
141
- if (id !== null) {
142
- const element = store.getElementByID(id);
143
-
144
- // Keep in mind that profiling data may be from a previous session.
145
- // In that case, IDs may match up arbitrarily; to be safe, compare both ID and display name.
146
- if (element !== null && element.displayName === name) {
141
+ // Keep in mind that profiling data may be from a previous session.
142
+ // If data has been imported, we should skip the selection sync.
143
+ if (
144
+ id !== null &&
145
+ profilingData !== null &&
146
+ profilingData.imported === false
147
+ ) {
148
+ // We should still check to see if this element is still in the store.
149
+ // It may have been removed during profiling.
150
+ if (store.containsElement(id)) {
151
dispatch({
152
type: 'SELECT_ELEMENT_BY_ID',
153
payload: id,
@@ -151,7 +155,7 @@ function ProfilerContextController({children}: Props) {
155
}
156
}
157
},
154
- [dispatch, selectFiberID, selectFiberName, store],
158
+ [dispatch, selectFiberID, selectFiberName, store, profilingData],
159
);
160
161
const setRootIDAndClearFiber = useCallback(
packages/react-devtools-shared/src/devtools/views/Profiler/types.js
+1
@@ -105,6 +105,7 @@ export type ProfilingDataForRootFrontend = {|
105
export type ProfilingDataFrontend = {|
106
// Profiling data per root.
107
dataForRoots: Map<number, ProfilingDataForRootFrontend>,
108
+ imported: boolean,
109
|};
110
111
export type CommitDataExport = {|
packages/react-devtools-shared/src/devtools/views/Profiler/utils.js
+2
-2
@@ -99,7 +99,7 @@ export function prepareProfilingDataFrontendFromBackendAndStore(
99
);
100
});
101
102
- return {dataForRoots};
102
+ return {dataForRoots, imported: false};
103
}
104
105
// Converts a Profiling data export into the format required by the Store.
@@ -156,7 +156,7 @@ export function prepareProfilingDataFrontendFromExport(
156
},
157
);
158
159
- return {dataForRoots};
159
+ return {dataForRoots, imported: true};
160
}
161
162
// Converts a Store Profiling data into a format that can be safely (JSON) serialized for export.