Skip to content

Commit e7f6210

Browse files
Emily Janzerfacebook-github-bot
Emily Janzer
authored andcommitted
Don't attempt to connect to React devtools every 2s
Summary: When testing out the NetworkOverlay, I noticed that we were creating a lot of WebSocket connections for localhost:8097. Rick found that this is because we're trying to connect to React devtools every 2 seconds: https://github.com/facebook/react/blob/master/packages/react-devtools-core/src/backend.js#L67 and it appears we create a new WebSocket every time. Dan suggested that we use opening the dev menu as a trigger for attempting to connect to React devtools. This diff uses RCTNativeAppEventEmitter to emit an event from native when the dev menu/dialog is shown, and listening to that event in JS to attempt to connect to devtools. I'm also making the change of passing in a websocket instead of just passing in the host + port; this way it will only attempt to connect once on each call to `connectToDevTools` (otherwise, we would attempt to reconnect every 2 seconds as soon as the dev menu is opened, and then the next time the menu is opened we'd so start that *again*, and so on - I could have it keep track of whether it's already connecting and avoid doing it again, but this is easier and should be sufficient, I think). We should probably also update the suggested troubleshooting tips on the devtools page to reflect this change, so that people don't get confused. Changelog: [General] [Fixed] Fix issue where we attempt to connect to React devtools every 2 seconds Reviewed By: mmmulani Differential Revision: D17919808 fbshipit-source-id: 4658d995c274574d22f2f54ea06d7f29ef2f54dc
1 parent c7ed398 commit e7f6210

File tree

4 files changed

+70
-34
lines changed

4 files changed

+70
-34
lines changed

Libraries/Core/setUpDeveloperTools.js

+1-34
Original file line numberDiff line numberDiff line change
@@ -24,40 +24,7 @@ if (__DEV__) {
2424
// TODO (T45803484) Enable devtools for bridgeless RN
2525
if (!global.RN$Bridgeless) {
2626
if (!global.__RCTProfileIsProfiling) {
27-
// not when debugging in chrome
28-
// TODO(t12832058) This check is broken
29-
if (!window.document) {
30-
const AppState = require('../AppState/AppState');
31-
// $FlowFixMe Module is untyped
32-
const reactDevTools = require('react-devtools-core');
33-
const getDevServer = require('./Devtools/getDevServer');
34-
35-
// Don't steal the DevTools from currently active app.
36-
// Note: if you add any AppState subscriptions to this file,
37-
// you will also need to guard against `AppState.isAvailable`,
38-
// or the code will throw for bundles that don't have it.
39-
const isAppActive = () => AppState.currentState !== 'background';
40-
41-
// Get hostname from development server (packager)
42-
const devServer = getDevServer();
43-
const host = devServer.bundleLoadedFromServer
44-
? devServer.url.replace(/https?:\/\//, '').split(':')[0]
45-
: 'localhost';
46-
47-
const viewConfig = require('../Components/View/ReactNativeViewViewConfig.js');
48-
49-
reactDevTools.connectToDevTools({
50-
isAppActive,
51-
host,
52-
// Read the optional global variable for backward compatibility.
53-
// It was added in https://github.com/facebook/react-native/commit/bf2b435322e89d0aeee8792b1c6e04656c2719a0.
54-
port: window.__REACT_DEVTOOLS_PORT__,
55-
resolveRNStyle: require('../StyleSheet/flattenStyle'),
56-
nativeStyleEditorValidAttributes: Object.keys(
57-
viewConfig.validAttributes.style,
58-
),
59-
});
60-
}
27+
require('./setUpReactDevTools');
6128

6229
// Set up inspector
6330
const JSInspector = require('../JSInspector/JSInspector');

Libraries/Core/setUpReactDevTools.js

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its 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+
* @format
9+
*/
10+
11+
'use strict';
12+
13+
if (__DEV__) {
14+
// $FlowFixMe Module is untyped
15+
const reactDevTools = require('react-devtools-core');
16+
const connectToDevTools = () => {
17+
// not when debugging in chrome
18+
// TODO(t12832058) This check is broken
19+
if (!window.document) {
20+
const AppState = require('../AppState/AppState');
21+
const getDevServer = require('./Devtools/getDevServer');
22+
23+
// Don't steal the DevTools from currently active app.
24+
// Note: if you add any AppState subscriptions to this file,
25+
// you will also need to guard against `AppState.isAvailable`,
26+
// or the code will throw for bundles that don't have it.
27+
const isAppActive = () => AppState.currentState !== 'background';
28+
29+
// Get hostname from development server (packager)
30+
const devServer = getDevServer();
31+
const host = devServer.bundleLoadedFromServer
32+
? devServer.url.replace(/https?:\/\//, '').split(':')[0]
33+
: 'localhost';
34+
35+
// Read the optional global variable for backward compatibility.
36+
// It was added in https://github.com/facebook/react-native/commit/bf2b435322e89d0aeee8792b1c6e04656c2719a0.
37+
const port =
38+
window.__REACT_DEVTOOLS_PORT__ != null
39+
? window.__REACT_DEVTOOLS_PORT__
40+
: 8097;
41+
42+
const WebSocket = require('../WebSocket/WebSocket');
43+
const ws = new WebSocket('ws://' + host + ':' + port);
44+
45+
const viewConfig = require('../Components/View/ReactNativeViewViewConfig.js');
46+
reactDevTools.connectToDevTools({
47+
isAppActive,
48+
resolveRNStyle: require('../StyleSheet/flattenStyle'),
49+
nativeStyleEditorValidAttributes: Object.keys(
50+
viewConfig.validAttributes.style,
51+
),
52+
websocket: ws,
53+
});
54+
}
55+
};
56+
57+
const RCTNativeAppEventEmitter = require('../EventEmitter/RCTNativeAppEventEmitter');
58+
RCTNativeAppEventEmitter.addListener('RCTDevMenuShown', connectToDevTools);
59+
connectToDevTools(); // Try connecting once on load
60+
}

React/DevSupport/RCTDevMenu.m

+5
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,11 @@ - (void)setDefaultJSBundle
424424

425425
_presentedItems = items;
426426
[RCTPresentedViewController() presentViewController:_actionSheet animated:YES completion:nil];
427+
428+
[_bridge enqueueJSCall:@"RCTNativeAppEventEmitter"
429+
method:@"emit"
430+
args:@[@"RCTDevMenuShown"]
431+
completion:NULL];
427432
}
428433

429434
- (RCTDevMenuAlertActionHandler)alertActionHandlerForDevItem:(RCTDevMenuItem *__nullable)item

ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerImpl.java

+4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import com.facebook.react.devsupport.interfaces.ErrorCustomizer;
4848
import com.facebook.react.devsupport.interfaces.PackagerStatusCallback;
4949
import com.facebook.react.devsupport.interfaces.StackFrame;
50+
import com.facebook.react.modules.core.RCTNativeAppEventEmitter;
5051
import com.facebook.react.modules.debug.interfaces.DeveloperSettings;
5152
import com.facebook.react.packagerconnection.RequestHandler;
5253
import com.facebook.react.packagerconnection.Responder;
@@ -621,6 +622,9 @@ public void onCancel(DialogInterface dialog) {
621622
})
622623
.create();
623624
mDevOptionsDialog.show();
625+
if (mCurrentContext != null) {
626+
mCurrentContext.getJSModule(RCTNativeAppEventEmitter.class).emit("RCTDevMenuShown", null);
627+
}
624628
}
625629

626630
/** Starts of stops the sampling profiler */

0 commit comments

Comments
 (0)