@samitouri / QOS-React-2 / commits / dd2e36df33

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.