Skip to content

Commit 9007fdc

Browse files
authored
[DOM] Shrink ReactDOMSharedInternals source representation (#28771)
Stacked on #28751 ReactDOMSharedInternals uses properties of considerable length to model mutuable state. These properties are not mangled during minification and contribute a not insigificant amount to the uncompressed bundle size and to a lesser degree compressed bundle size. This change rewrites the DOMInternals in a way that shortens property names so we can have smaller builds. It also treats the entire object as a mutable container rather than having different mutable sub objects. The same treatment should be given to ReactSharedInternals
1 parent 14f50ad commit 9007fdc

15 files changed

+357
-136
lines changed

packages/react-dom-bindings/src/client/ReactDOMUpdatePriority.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ export function setCurrentUpdatePriority(
2525
// is much longer. I hope this is consistent enough to rely on across builds
2626
IntentionallyUnusedArgument?: empty,
2727
): void {
28-
ReactDOMSharedInternals.up = newPriority;
28+
ReactDOMSharedInternals.p /* currentUpdatePriority */ = newPriority;
2929
}
3030

3131
export function getCurrentUpdatePriority(): EventPriority {
32-
return ReactDOMSharedInternals.up;
32+
return ReactDOMSharedInternals.p; /* currentUpdatePriority */
3333
}
3434

3535
export function resolveUpdatePriority(): EventPriority {
36-
const updatePriority = ReactDOMSharedInternals.up;
36+
const updatePriority = ReactDOMSharedInternals.p; /* currentUpdatePriority */
3737
if (updatePriority !== NoEventPriority) {
3838
return updatePriority;
3939
}

packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,6 @@ import escapeSelectorAttributeValueInsideDoubleQuotes from './escapeSelectorAttr
104104
import {flushSyncWork as flushSyncWorkOnAllRoots} from 'react-reconciler/src/ReactFiberWorkLoop';
105105

106106
import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals';
107-
const ReactDOMCurrentDispatcher =
108-
ReactDOMSharedInternals.ReactDOMCurrentDispatcher;
109107

110108
export type Type = string;
111109
export type Props = {
@@ -1924,8 +1922,9 @@ function getDocumentFromRoot(root: HoistableRoot): Document {
19241922
return root.ownerDocument || root;
19251923
}
19261924

1927-
const previousDispatcher = ReactDOMCurrentDispatcher.current;
1928-
ReactDOMCurrentDispatcher.current = {
1925+
const previousDispatcher =
1926+
ReactDOMSharedInternals.d; /* ReactDOMCurrentDispatcher */
1927+
ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */ = {
19291928
flushSyncWork: disableLegacyMode
19301929
? flushSyncWork
19311930
: previousDispatcher.flushSyncWork,

packages/react-dom-bindings/src/server/ReactDOMFlightServerHostDispatcher.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,10 @@ import {
2323
} from 'react-server/src/ReactFlightServer';
2424

2525
import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals';
26-
const ReactDOMCurrentDispatcher =
27-
ReactDOMSharedInternals.ReactDOMCurrentDispatcher;
2826

29-
const previousDispatcher = ReactDOMCurrentDispatcher.current;
30-
ReactDOMCurrentDispatcher.current = {
27+
const previousDispatcher =
28+
ReactDOMSharedInternals.d; /* ReactDOMCurrentDispatcher */
29+
ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */ = {
3130
flushSyncWork: previousDispatcher.flushSyncWork,
3231
prefetchDNS,
3332
preconnect,

packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,10 @@ import {getValueDescriptorExpectingObjectForWarning} from '../shared/ReactDOMRes
8383
import {NotPending} from '../shared/ReactDOMFormActions';
8484

8585
import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals';
86-
const ReactDOMCurrentDispatcher =
87-
ReactDOMSharedInternals.ReactDOMCurrentDispatcher;
8886

89-
const previousDispatcher = ReactDOMCurrentDispatcher.current;
90-
ReactDOMCurrentDispatcher.current = {
87+
const previousDispatcher =
88+
ReactDOMSharedInternals.d; /* ReactDOMCurrentDispatcher */
89+
ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */ = {
9190
flushSyncWork: previousDispatcher.flushSyncWork,
9291
prefetchDNS,
9392
preconnect,

packages/react-dom-bindings/src/shared/ReactFlightClientConfigDOM.js

+5-11
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,14 @@
1313
import type {HintCode, HintModel} from '../server/ReactFlightServerConfigDOM';
1414

1515
import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals';
16-
const ReactDOMCurrentDispatcher =
17-
ReactDOMSharedInternals.ReactDOMCurrentDispatcher;
1816

1917
import {getCrossOriginString} from './crossOriginStrings';
2018

2119
export function dispatchHint<Code: HintCode>(
2220
code: Code,
2321
model: HintModel<Code>,
2422
): void {
25-
const dispatcher = ReactDOMCurrentDispatcher.current;
23+
const dispatcher = ReactDOMSharedInternals.d; /* ReactDOMCurrentDispatcher */
2624
switch (code) {
2725
case 'D': {
2826
const refined = refineModel(code, model);
@@ -117,25 +115,21 @@ export function preinitModuleForSSR(
117115
nonce: ?string,
118116
crossOrigin: ?string,
119117
) {
120-
const dispatcher = ReactDOMCurrentDispatcher.current;
121-
if (dispatcher) {
122-
dispatcher.preinitModuleScript(href, {
118+
ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */
119+
.preinitModuleScript(href, {
123120
crossOrigin: getCrossOriginString(crossOrigin),
124121
nonce,
125122
});
126-
}
127123
}
128124

129125
export function preinitScriptForSSR(
130126
href: string,
131127
nonce: ?string,
132128
crossOrigin: ?string,
133129
) {
134-
const dispatcher = ReactDOMCurrentDispatcher.current;
135-
if (dispatcher) {
136-
dispatcher.preinitScript(href, {
130+
ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */
131+
.preinitScript(href, {
137132
crossOrigin: getCrossOriginString(crossOrigin),
138133
nonce,
139134
});
140-
}
141135
}

packages/react-dom/client.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ export function createRoot(
2727
options?: CreateRootOptions,
2828
): RootType {
2929
if (__DEV__) {
30-
Internals.usingClientEntryPoint = true;
30+
(Internals: any).usingClientEntryPoint = true;
3131
}
3232
try {
3333
return createRootImpl(container, options);
3434
} finally {
3535
if (__DEV__) {
36-
Internals.usingClientEntryPoint = false;
36+
(Internals: any).usingClientEntryPoint = false;
3737
}
3838
}
3939
}
@@ -44,13 +44,13 @@ export function hydrateRoot(
4444
options?: HydrateRootOptions,
4545
): RootType {
4646
if (__DEV__) {
47-
Internals.usingClientEntryPoint = true;
47+
(Internals: any).usingClientEntryPoint = true;
4848
}
4949
try {
5050
return hydrateRootImpl(container, children, options);
5151
} finally {
5252
if (__DEV__) {
53-
Internals.usingClientEntryPoint = false;
53+
(Internals: any).usingClientEntryPoint = false;
5454
}
5555
}
5656
}

packages/react-dom/index.classic.fb.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
import {isEnabled} from 'react-dom-bindings/src/events/ReactDOMEventListener';
1111

12-
import Internals from './src/ReactDOMSharedInternals';
12+
import Internals from './src/ReactDOMSharedInternalsFB';
1313

1414
// For classic WWW builds, include a few internals that are already in use.
1515
Object.assign((Internals: any), {
@@ -32,7 +32,7 @@ export {
3232
preinit,
3333
preinitModule,
3434
version,
35-
} from './src/client/ReactDOM';
35+
} from './src/client/ReactDOMFB';
3636

3737
export {
3838
createRoot,

packages/react-dom/index.modern.fb.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @flow
88
*/
99

10-
export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMSharedInternals';
10+
export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMSharedInternalsFB';
1111
export {
1212
createPortal,
1313
flushSync,
@@ -23,6 +23,6 @@ export {
2323
preinit,
2424
preinitModule,
2525
version,
26-
} from './src/client/ReactDOM';
26+
} from './src/client/ReactDOMFB';
2727

2828
export {createRoot, hydrateRoot} from './src/client/ReactDOMRootFB';

packages/react-dom/src/ReactDOMSharedInternals.js

+16-14
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,19 @@ import type {HostDispatcher} from './shared/ReactDOMTypes';
1212

1313
import {NoEventPriority} from 'react-reconciler/src/ReactEventPriorities';
1414

15-
type InternalsType = {
16-
usingClientEntryPoint: boolean,
17-
Events: [any, any, any, any, any, any],
18-
ReactDOMCurrentDispatcher: {
19-
current: HostDispatcher,
20-
},
15+
type ReactDOMInternals = {
16+
d /* ReactDOMCurrentDispatcher */: HostDispatcher,
17+
p /* currentUpdatePriority */: EventPriority,
2118
findDOMNode:
2219
| null
2320
| ((
2421
componentOrElement: React$Component<any, any>,
2522
) => null | Element | Text),
26-
up /* currentUpdatePriority */: EventPriority,
23+
usingClientEntryPoint: boolean,
24+
};
25+
26+
export type ReactDOMInternalsDev = ReactDOMInternals & {
27+
usingClientEntryPoint: boolean,
2728
};
2829

2930
function noop() {}
@@ -39,14 +40,15 @@ const DefaultDispatcher: HostDispatcher = {
3940
preinitModuleScript: noop,
4041
};
4142

42-
const Internals: InternalsType = {
43-
usingClientEntryPoint: false,
44-
Events: (null: any),
45-
ReactDOMCurrentDispatcher: {
46-
current: DefaultDispatcher,
47-
},
43+
const Internals: ReactDOMInternals = {
44+
d /* ReactDOMCurrentDispatcher */: DefaultDispatcher,
45+
p /* currentUpdatePriority */: NoEventPriority,
4846
findDOMNode: null,
49-
up /* currentUpdatePriority */: NoEventPriority,
47+
usingClientEntryPoint: false,
5048
};
5149

50+
// if (__DEV__) {
51+
// (Internals: any).usingClientEntryPoint = false;
52+
// }
53+
5254
export default Internals;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
import type {EventPriority} from 'react-reconciler/src/ReactEventPriorities';
11+
import type {HostDispatcher} from './shared/ReactDOMTypes';
12+
13+
import {NoEventPriority} from 'react-reconciler/src/ReactEventPriorities';
14+
15+
type ReactDOMInternals = {
16+
Events: [any, any, any, any, any, any],
17+
d /* ReactDOMCurrentDispatcher */: HostDispatcher,
18+
p /* currentUpdatePriority */: EventPriority,
19+
findDOMNode:
20+
| null
21+
| ((
22+
componentOrElement: React$Component<any, any>,
23+
) => null | Element | Text),
24+
};
25+
26+
function noop() {}
27+
28+
const DefaultDispatcher: HostDispatcher = {
29+
flushSyncWork: noop,
30+
prefetchDNS: noop,
31+
preconnect: noop,
32+
preload: noop,
33+
preloadModule: noop,
34+
preinitScript: noop,
35+
preinitStyle: noop,
36+
preinitModuleScript: noop,
37+
};
38+
39+
const Internals: ReactDOMInternals = {
40+
Events: (null: any),
41+
d /* ReactDOMCurrentDispatcher */: DefaultDispatcher,
42+
p /* currentUpdatePriority */: NoEventPriority,
43+
findDOMNode: null,
44+
};
45+
46+
export default Internals;

packages/react-dom/src/client/ReactDOM.js

+3-23
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,7 @@ import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal
3434
import {canUseDOM} from 'shared/ExecutionEnvironment';
3535
import ReactVersion from 'shared/ReactVersion';
3636

37-
import {
38-
getClosestInstanceFromNode,
39-
getInstanceFromNode,
40-
getNodeFromInstance,
41-
getFiberCurrentPropsFromNode,
42-
} from 'react-dom-bindings/src/client/ReactDOMComponentTree';
43-
import {
44-
enqueueStateRestore,
45-
restoreStateIfNeeded,
46-
} from 'react-dom-bindings/src/events/ReactDOMControlledComponent';
37+
import {getClosestInstanceFromNode} from 'react-dom-bindings/src/client/ReactDOMComponentTree';
4738
import Internals from '../ReactDOMSharedInternals';
4839

4940
export {
@@ -97,7 +88,7 @@ function createRoot(
9788
options?: CreateRootOptions,
9889
): RootType {
9990
if (__DEV__) {
100-
if (!Internals.usingClientEntryPoint && !__UMD__) {
91+
if (!(Internals: any).usingClientEntryPoint && !__UMD__) {
10192
console.error(
10293
'You are importing createRoot from "react-dom" which is not supported. ' +
10394
'You should instead import it from "react-dom/client".',
@@ -113,7 +104,7 @@ function hydrateRoot(
113104
options?: HydrateRootOptions,
114105
): RootType {
115106
if (__DEV__) {
116-
if (!Internals.usingClientEntryPoint && !__UMD__) {
107+
if (!(Internals: any).usingClientEntryPoint && !__UMD__) {
117108
console.error(
118109
'You are importing hydrateRoot from "react-dom" which is not supported. ' +
119110
'You should instead import it from "react-dom/client".',
@@ -177,17 +168,6 @@ export {
177168
runWithPriority as unstable_runWithPriority,
178169
};
179170

180-
// Keep in sync with ReactTestUtils.js.
181-
// This is an array for better minification.
182-
Internals.Events = [
183-
getInstanceFromNode,
184-
getNodeFromInstance,
185-
getFiberCurrentPropsFromNode,
186-
enqueueStateRestore,
187-
restoreStateIfNeeded,
188-
unstable_batchedUpdates,
189-
];
190-
191171
const foundDevTools = injectIntoDevTools({
192172
findFiberByHostInstance: getClosestInstanceFromNode,
193173
bundleType: __DEV__ ? 1 : 0,

0 commit comments

Comments
 (0)