Skip to content

Commit

Permalink
[DOM] Shrink ReactDOMSharedInternals source representation (#28771)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
gnoff authored and rickhanlonii committed Apr 11, 2024
1 parent 6f396bb commit 735a55d
Show file tree
Hide file tree
Showing 15 changed files with 357 additions and 136 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ export function setCurrentUpdatePriority(
// is much longer. I hope this is consistent enough to rely on across builds
IntentionallyUnusedArgument?: empty,
): void {
ReactDOMSharedInternals.up = newPriority;
ReactDOMSharedInternals.p /* currentUpdatePriority */ = newPriority;
}

export function getCurrentUpdatePriority(): EventPriority {
return ReactDOMSharedInternals.up;
return ReactDOMSharedInternals.p; /* currentUpdatePriority */
}

export function resolveUpdatePriority(): EventPriority {
const updatePriority = ReactDOMSharedInternals.up;
const updatePriority = ReactDOMSharedInternals.p; /* currentUpdatePriority */
if (updatePriority !== NoEventPriority) {
return updatePriority;
}
Expand Down
7 changes: 3 additions & 4 deletions packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ import escapeSelectorAttributeValueInsideDoubleQuotes from './escapeSelectorAttr
import {flushSyncWork as flushSyncWorkOnAllRoots} from 'react-reconciler/src/ReactFiberWorkLoop';

import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals';
const ReactDOMCurrentDispatcher =
ReactDOMSharedInternals.ReactDOMCurrentDispatcher;

export type Type = string;
export type Props = {
Expand Down Expand Up @@ -1924,8 +1922,9 @@ function getDocumentFromRoot(root: HoistableRoot): Document {
return root.ownerDocument || root;
}

const previousDispatcher = ReactDOMCurrentDispatcher.current;
ReactDOMCurrentDispatcher.current = {
const previousDispatcher =
ReactDOMSharedInternals.d; /* ReactDOMCurrentDispatcher */
ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */ = {
flushSyncWork: disableLegacyMode
? flushSyncWork
: previousDispatcher.flushSyncWork,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ import {
} from 'react-server/src/ReactFlightServer';

import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals';
const ReactDOMCurrentDispatcher =
ReactDOMSharedInternals.ReactDOMCurrentDispatcher;

const previousDispatcher = ReactDOMCurrentDispatcher.current;
ReactDOMCurrentDispatcher.current = {
const previousDispatcher =
ReactDOMSharedInternals.d; /* ReactDOMCurrentDispatcher */
ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */ = {
flushSyncWork: previousDispatcher.flushSyncWork,
prefetchDNS,
preconnect,
Expand Down
7 changes: 3 additions & 4 deletions packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,10 @@ import {getValueDescriptorExpectingObjectForWarning} from '../shared/ReactDOMRes
import {NotPending} from '../shared/ReactDOMFormActions';

import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals';
const ReactDOMCurrentDispatcher =
ReactDOMSharedInternals.ReactDOMCurrentDispatcher;

const previousDispatcher = ReactDOMCurrentDispatcher.current;
ReactDOMCurrentDispatcher.current = {
const previousDispatcher =
ReactDOMSharedInternals.d; /* ReactDOMCurrentDispatcher */
ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */ = {
flushSyncWork: previousDispatcher.flushSyncWork,
prefetchDNS,
preconnect,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,14 @@
import type {HintCode, HintModel} from '../server/ReactFlightServerConfigDOM';

import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals';
const ReactDOMCurrentDispatcher =
ReactDOMSharedInternals.ReactDOMCurrentDispatcher;

import {getCrossOriginString} from './crossOriginStrings';

export function dispatchHint<Code: HintCode>(
code: Code,
model: HintModel<Code>,
): void {
const dispatcher = ReactDOMCurrentDispatcher.current;
const dispatcher = ReactDOMSharedInternals.d; /* ReactDOMCurrentDispatcher */
switch (code) {
case 'D': {
const refined = refineModel(code, model);
Expand Down Expand Up @@ -117,25 +115,21 @@ export function preinitModuleForSSR(
nonce: ?string,
crossOrigin: ?string,
) {
const dispatcher = ReactDOMCurrentDispatcher.current;
if (dispatcher) {
dispatcher.preinitModuleScript(href, {
ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */
.preinitModuleScript(href, {
crossOrigin: getCrossOriginString(crossOrigin),
nonce,
});
}
}

export function preinitScriptForSSR(
href: string,
nonce: ?string,
crossOrigin: ?string,
) {
const dispatcher = ReactDOMCurrentDispatcher.current;
if (dispatcher) {
dispatcher.preinitScript(href, {
ReactDOMSharedInternals.d /* ReactDOMCurrentDispatcher */
.preinitScript(href, {
crossOrigin: getCrossOriginString(crossOrigin),
nonce,
});
}
}
8 changes: 4 additions & 4 deletions packages/react-dom/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ export function createRoot(
options?: CreateRootOptions,
): RootType {
if (__DEV__) {
Internals.usingClientEntryPoint = true;
(Internals: any).usingClientEntryPoint = true;
}
try {
return createRootImpl(container, options);
} finally {
if (__DEV__) {
Internals.usingClientEntryPoint = false;
(Internals: any).usingClientEntryPoint = false;
}
}
}
Expand All @@ -44,13 +44,13 @@ export function hydrateRoot(
options?: HydrateRootOptions,
): RootType {
if (__DEV__) {
Internals.usingClientEntryPoint = true;
(Internals: any).usingClientEntryPoint = true;
}
try {
return hydrateRootImpl(container, children, options);
} finally {
if (__DEV__) {
Internals.usingClientEntryPoint = false;
(Internals: any).usingClientEntryPoint = false;
}
}
}
4 changes: 2 additions & 2 deletions packages/react-dom/index.classic.fb.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

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

import Internals from './src/ReactDOMSharedInternals';
import Internals from './src/ReactDOMSharedInternalsFB';

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

export {
createRoot,
Expand Down
4 changes: 2 additions & 2 deletions packages/react-dom/index.modern.fb.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @flow
*/

export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMSharedInternals';
export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './src/ReactDOMSharedInternalsFB';
export {
createPortal,
flushSync,
Expand All @@ -23,6 +23,6 @@ export {
preinit,
preinitModule,
version,
} from './src/client/ReactDOM';
} from './src/client/ReactDOMFB';

export {createRoot, hydrateRoot} from './src/client/ReactDOMRootFB';
30 changes: 16 additions & 14 deletions packages/react-dom/src/ReactDOMSharedInternals.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,19 @@ import type {HostDispatcher} from './shared/ReactDOMTypes';

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

type InternalsType = {
usingClientEntryPoint: boolean,
Events: [any, any, any, any, any, any],
ReactDOMCurrentDispatcher: {
current: HostDispatcher,
},
type ReactDOMInternals = {
d /* ReactDOMCurrentDispatcher */: HostDispatcher,
p /* currentUpdatePriority */: EventPriority,
findDOMNode:
| null
| ((
componentOrElement: React$Component<any, any>,
) => null | Element | Text),
up /* currentUpdatePriority */: EventPriority,
usingClientEntryPoint: boolean,
};

export type ReactDOMInternalsDev = ReactDOMInternals & {
usingClientEntryPoint: boolean,
};

function noop() {}
Expand All @@ -39,14 +40,15 @@ const DefaultDispatcher: HostDispatcher = {
preinitModuleScript: noop,
};

const Internals: InternalsType = {
usingClientEntryPoint: false,
Events: (null: any),
ReactDOMCurrentDispatcher: {
current: DefaultDispatcher,
},
const Internals: ReactDOMInternals = {
d /* ReactDOMCurrentDispatcher */: DefaultDispatcher,
p /* currentUpdatePriority */: NoEventPriority,
findDOMNode: null,
up /* currentUpdatePriority */: NoEventPriority,
usingClientEntryPoint: false,
};

// if (__DEV__) {
// (Internals: any).usingClientEntryPoint = false;
// }

export default Internals;
46 changes: 46 additions & 0 deletions packages/react-dom/src/ReactDOMSharedInternalsFB.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import type {EventPriority} from 'react-reconciler/src/ReactEventPriorities';
import type {HostDispatcher} from './shared/ReactDOMTypes';

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

type ReactDOMInternals = {
Events: [any, any, any, any, any, any],
d /* ReactDOMCurrentDispatcher */: HostDispatcher,
p /* currentUpdatePriority */: EventPriority,
findDOMNode:
| null
| ((
componentOrElement: React$Component<any, any>,
) => null | Element | Text),
};

function noop() {}

const DefaultDispatcher: HostDispatcher = {
flushSyncWork: noop,
prefetchDNS: noop,
preconnect: noop,
preload: noop,
preloadModule: noop,
preinitScript: noop,
preinitStyle: noop,
preinitModuleScript: noop,
};

const Internals: ReactDOMInternals = {
Events: (null: any),
d /* ReactDOMCurrentDispatcher */: DefaultDispatcher,
p /* currentUpdatePriority */: NoEventPriority,
findDOMNode: null,
};

export default Internals;
26 changes: 3 additions & 23 deletions packages/react-dom/src/client/ReactDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,7 @@ import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal
import {canUseDOM} from 'shared/ExecutionEnvironment';
import ReactVersion from 'shared/ReactVersion';

import {
getClosestInstanceFromNode,
getInstanceFromNode,
getNodeFromInstance,
getFiberCurrentPropsFromNode,
} from 'react-dom-bindings/src/client/ReactDOMComponentTree';
import {
enqueueStateRestore,
restoreStateIfNeeded,
} from 'react-dom-bindings/src/events/ReactDOMControlledComponent';
import {getClosestInstanceFromNode} from 'react-dom-bindings/src/client/ReactDOMComponentTree';
import Internals from '../ReactDOMSharedInternals';

export {
Expand Down Expand Up @@ -97,7 +88,7 @@ function createRoot(
options?: CreateRootOptions,
): RootType {
if (__DEV__) {
if (!Internals.usingClientEntryPoint && !__UMD__) {
if (!(Internals: any).usingClientEntryPoint && !__UMD__) {
console.error(
'You are importing createRoot from "react-dom" which is not supported. ' +
'You should instead import it from "react-dom/client".',
Expand All @@ -113,7 +104,7 @@ function hydrateRoot(
options?: HydrateRootOptions,
): RootType {
if (__DEV__) {
if (!Internals.usingClientEntryPoint && !__UMD__) {
if (!(Internals: any).usingClientEntryPoint && !__UMD__) {
console.error(
'You are importing hydrateRoot from "react-dom" which is not supported. ' +
'You should instead import it from "react-dom/client".',
Expand Down Expand Up @@ -177,17 +168,6 @@ export {
runWithPriority as unstable_runWithPriority,
};

// Keep in sync with ReactTestUtils.js.
// This is an array for better minification.
Internals.Events = [
getInstanceFromNode,
getNodeFromInstance,
getFiberCurrentPropsFromNode,
enqueueStateRestore,
restoreStateIfNeeded,
unstable_batchedUpdates,
];

const foundDevTools = injectIntoDevTools({
findFiberByHostInstance: getClosestInstanceFromNode,
bundleType: __DEV__ ? 1 : 0,
Expand Down
Loading

0 comments on commit 735a55d

Please sign in to comment.