Remove an extra allocation for open source bundles (#11797)
* Remove EventListener fbjs utility EventListener normalizes event subscription for <= IE8. This is no longer necessary. element.addEventListener is sufficient. * Remove an extra allocation for open source bundles * Split into two functions to avoid extra runtime checks * Revert unrelated changes
Dan Abramov committed
Dec 7, 2017 at 22:28 UTC
f93e34e98052d7bb6594bd02012e13432e039445
5 files changed
+82
-3
packages/react-dom/src/events/EventListener.js
new
+24
@@ -0,0 +1,24 @@
1
+/**
2
+ * Copyright (c) 2013-present, Facebook, Inc.
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
+export function addEventBubbleListener(
11
+ element: Element,
12
+ eventType: string,
13
+ listener: Function,
14
+): void {
15
+ element.addEventListener(eventType, listener, false);
16
+}
17
+
18
+export function addEventCaptureListener(
19
+ element: Element,
20
+ eventType: string,
21
+ listener: Function,
22
+): void {
23
+ element.addEventListener(eventType, listener, true);
24
+}
packages/react-dom/src/events/ReactDOMEventListener.js
+3
-3
@@ -8,8 +8,8 @@
8
import {batchedUpdates} from 'events/ReactGenericBatching';
9
import {isFiberMounted} from 'react-reconciler/reflection';
10
import {HostRoot} from 'shared/ReactTypeOfWork';
11
-import EventListener from 'fbjs/lib/EventListener';
11
12
+import {addEventBubbleListener, addEventCaptureListener} from './EventListener';
13
import getEventTarget from './getEventTarget';
14
import {getClosestInstanceFromNode} from '../client/ReactDOMComponentTree';
15
@@ -124,7 +124,7 @@ export function trapBubbledEvent(topLevelType, handlerBaseName, element) {
124
if (!element) {
125
return null;
126
}
127
- return EventListener.listen(
127
+ addEventBubbleListener(
128
element,
129
handlerBaseName,
130
dispatchEvent.bind(null, topLevelType),
@@ -145,7 +145,7 @@ export function trapCapturedEvent(topLevelType, handlerBaseName, element) {
145
if (!element) {
146
return null;
147
}
148
- return EventListener.capture(
148
+ addEventCaptureListener(
149
element,
150
handlerBaseName,
151
dispatchEvent.bind(null, topLevelType),
packages/react-dom/src/events/forks/EventListener-www.js
new
+35
@@ -0,0 +1,35 @@
1
+/**
2
+ * Copyright (c) 2013-present, Facebook, Inc.
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
+var EventListenerWWW = require('EventListener');
11
+
12
+import typeof * as EventListenerType from '../EventListener';
13
+import typeof * as EventListenerShimType from './EventListener-www';
14
+
15
+export function addEventBubbleListener(
16
+ element: Element,
17
+ eventType: string,
18
+ listener: Function,
19
+): void {
20
+ EventListenerWWW.listen(element, eventType, listener);
21
+}
22
+
23
+export function addEventCaptureListener(
24
+ element: Element,
25
+ eventType: string,
26
+ listener: Function,
27
+): void {
28
+ EventListenerWWW.capture(element, eventType, listener);
29
+}
30
+
31
+// Flow magic to verify the exports of this file match the original version.
32
+// eslint-disable-next-line no-unused-vars
33
+type Check<_X, Y: _X, X: Y = _X> = null;
34
+// eslint-disable-next-line no-unused-expressions
35
+(null: Check<EventListenerShimType, EventListenerType>);
scripts/flow/environment.js
+8
@@ -24,3 +24,11 @@ declare module 'ReactFiberErrorDialog' {
24
showErrorDialog: (error: mixed) => boolean,
25
};
26
}
27
+
28
+// EventListener www fork
29
+declare module 'EventListener' {
30
+ declare module.exports: {
31
+ listen: (target: Element, type: string, callback: Function) => mixed,
32
+ capture: (target: Element, type: string, callback: Function) => mixed,
33
+ };
34
+}
scripts/rollup/forks.js
+12
@@ -101,6 +101,18 @@ const forks = Object.freeze({
101
return null;
102
}
103
},
104
+
105
+ // We wrap top-level listeners into guards on www.
106
+ 'react-dom/src/events/EventListener': (bundleType, entry) => {
107
+ switch (bundleType) {
108
+ case FB_DEV:
109
+ case FB_PROD:
110
+ // Use the www fork which is integrated with TimeSlice profiling.
111
+ return 'react-dom/src/events/forks/EventListener-www.js';
112
+ default:
113
+ return null;
114
+ }
115
+ },
116
});
117
118
module.exports = forks;