Skip to content

Commit de091bc

Browse files
author
Brian Vaughn
committed
DevTools: Separate named hooks I/O and CPU code
I/O code has been moved into a file (loadSourceAndMetadata) that runs on the main/UI thread. CPU code has been moved into a file (parseSourceAndMetadata) that runs in a web worker (except for Jest tests). This is being done to increase the likelihood of re-using cached source files when fetching from the network.
1 parent 8723e77 commit de091bc

File tree

9 files changed

+973
-780
lines changed

9 files changed

+973
-780
lines changed

packages/react-devtools-extensions/src/__tests__/parseHookNames-test.js

+28-7
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,24 @@ describe('parseHookNames', () => {
4242

4343
inspectHooks = require('react-debug-tools/src/ReactDebugHooks')
4444
.inspectHooks;
45-
parseHookNames = require('../parseHookNames/parseHookNames').parseHookNames;
45+
46+
// Jest can't run the workerized version of this module.
47+
const loadSourceAndMetadata = require('../parseHookNames/loadSourceAndMetadata')
48+
.default;
49+
const parseSourceAndMetadata = require('../parseHookNames/parseSourceAndMetadata')
50+
.parseSourceAndMetadata;
51+
parseHookNames = async hooksTree => {
52+
const [
53+
hooksList,
54+
locationKeyToHookSourceAndMetadata,
55+
] = await loadSourceAndMetadata(hooksTree);
56+
57+
// Runs in a Worker because it's CPU intensive:
58+
return parseSourceAndMetadata(
59+
hooksList,
60+
locationKeyToHookSourceAndMetadata,
61+
);
62+
};
4663

4764
// Jest (jest-runner?) configures Errors to automatically account for source maps.
4865
// This changes behavior between our tests and the browser.
@@ -880,18 +897,21 @@ describe('parseHookNames', () => {
880897
describe('parseHookNames worker', () => {
881898
let inspectHooks;
882899
let parseHookNames;
883-
let workerizedParseHookNamesMock;
900+
let workerizedParseSourceAndMetadataMock;
884901

885902
beforeEach(() => {
886903
window.Worker = undefined;
887904

888-
workerizedParseHookNamesMock = jest.fn();
905+
workerizedParseSourceAndMetadataMock = jest.fn(() => {
906+
console.log('mock fn');
907+
return [];
908+
});
889909

890-
jest.mock('../parseHookNames/parseHookNames.worker.js', () => {
910+
jest.mock('../parseHookNames/parseSourceAndMetadata.worker.js', () => {
891911
return {
892912
__esModule: true,
893913
default: () => ({
894-
parseHookNames: workerizedParseHookNamesMock,
914+
parseSourceAndMetadata: workerizedParseSourceAndMetadataMock,
895915
}),
896916
};
897917
});
@@ -912,11 +932,12 @@ describe('parseHookNames worker', () => {
912932
.Component;
913933

914934
window.Worker = true;
915-
// resets module so mocked worker instance can be updated
935+
936+
// Reset module so mocked worker instance can be updated.
916937
jest.resetModules();
917938
parseHookNames = require('../parseHookNames').parseHookNames;
918939

919940
await getHookNamesForComponent(Component);
920-
expect(workerizedParseHookNamesMock).toHaveBeenCalledTimes(1);
941+
expect(workerizedParseSourceAndMetadataMock).toHaveBeenCalledTimes(1);
921942
});
922943
});

packages/react-devtools-extensions/src/parseHookNames/index.js

+29-8
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,38 @@
77
* @flow
88
*/
99

10-
// This file uses workerize to load ./parseHookNames.worker as a webworker and instanciates it,
11-
// exposing flow typed functions that can be used on other files.
10+
import type {HookSourceAndMetadata} from './loadSourceAndMetadata';
11+
import type {HooksNode, HooksTree} from 'react-debug-tools/src/ReactDebugHooks';
12+
import type {HookNames} from 'react-devtools-shared/src/types';
1213

13-
import WorkerizedParseHookNames from './parseHookNames.worker';
14-
import typeof * as ParseHookNamesModule from './parseHookNames';
14+
import WorkerizedParseSourceAndMetadata from './parseSourceAndMetadata.worker';
15+
import typeof * as ParseSourceAndMetadataModule from './parseSourceAndMetadata';
1516

16-
const workerizedParseHookNames: ParseHookNamesModule = WorkerizedParseHookNames();
17+
import loadSourceAndMetadata from './loadSourceAndMetadata';
1718

18-
type ParseHookNames = $PropertyType<ParseHookNamesModule, 'parseHookNames'>;
19+
const workerizedParseHookNames: ParseSourceAndMetadataModule = WorkerizedParseSourceAndMetadata();
1920

20-
export const parseHookNames: ParseHookNames = hooksTree =>
21-
workerizedParseHookNames.parseHookNames(hooksTree);
21+
export function parseSourceAndMetadata(
22+
hooksList: Array<HooksNode>,
23+
locationKeyToHookSourceAndMetadata: Map<string, HookSourceAndMetadata>,
24+
): Promise<HookNames | null> {
25+
return workerizedParseHookNames.parseSourceAndMetadata(
26+
hooksList,
27+
locationKeyToHookSourceAndMetadata,
28+
);
29+
}
2230

2331
export const purgeCachedMetadata = workerizedParseHookNames.purgeCachedMetadata;
32+
33+
export async function parseHookNames(
34+
hooksTree: HooksTree,
35+
): Promise<HookNames | null> {
36+
// Runs on the main/UI thread so it can reuse Network cache:
37+
const [
38+
hooksList,
39+
locationKeyToHookSourceAndMetadata,
40+
] = await loadSourceAndMetadata(hooksTree);
41+
42+
// Runs in a Worker because it's CPU intensive:
43+
return parseSourceAndMetadata(hooksList, locationKeyToHookSourceAndMetadata);
44+
}

0 commit comments

Comments
 (0)