From 3a031cc93a87834c3b63f96f12a8b3cdb94d3eb6 Mon Sep 17 00:00:00 2001 From: Alexey Lang Date: Thu, 10 Aug 2017 04:09:52 -0700 Subject: [PATCH] Bring back React Stack support Reviewed By: javache Differential Revision: D5547208 fbshipit-source-id: 25cef6aa27fc4f17b26e1088256819ea235f79cf --- Libraries/Core/InitializeCore.js | 5 -- Libraries/Performance/Systrace.js | 62 ++++++++++++++++++- .../Renderer/shims/ReactNativeFeatureFlags.js | 4 ++ 3 files changed, 64 insertions(+), 7 deletions(-) diff --git a/Libraries/Core/InitializeCore.js b/Libraries/Core/InitializeCore.js index 80b3687b3..fd239f119 100644 --- a/Libraries/Core/InitializeCore.js +++ b/Libraries/Core/InitializeCore.js @@ -95,11 +95,6 @@ if (global.__RCTProfileIsProfiling) { Systrace.setEnabled(true); } -if (__DEV__ && global.performance === undefined) { - const Systrace = require('Systrace'); - global.performance = Systrace.getUserTimingPolyfill(); -} - // Set up console const ExceptionsManager = require('ExceptionsManager'); ExceptionsManager.installConsoleErrorReporter(); diff --git a/Libraries/Performance/Systrace.js b/Libraries/Performance/Systrace.js index 8db4ad99e..abcb66ca1 100644 --- a/Libraries/Performance/Systrace.js +++ b/Libraries/Performance/Systrace.js @@ -33,6 +33,8 @@ let _enabled = false; let _asyncCookie = 0; const _markStack = []; let _markStackIndex = -1; +let _canInstallReactHook = false; +let _useFiber = false; // Implements a subset of User Timing API necessary for React measurements. // https://developer.mozilla.org/en-US/docs/Web/API/User_Timing_API @@ -102,9 +104,53 @@ const userTimingPolyfill = { }, }; +// A hook to get React Stack markers in Systrace. +const reactDebugToolHook = { + onBeforeMountComponent(debugID) { + const ReactComponentTreeHook = require('ReactGlobalSharedState').ReactComponentTreeHook; + const displayName = ReactComponentTreeHook.getDisplayName(debugID); + Systrace.beginEvent(`ReactReconciler.mountComponent(${displayName})`); + }, + onMountComponent(debugID) { + Systrace.endEvent(); + }, + onBeforeUpdateComponent(debugID) { + const ReactComponentTreeHook = require('ReactGlobalSharedState').ReactComponentTreeHook; + const displayName = ReactComponentTreeHook.getDisplayName(debugID); + Systrace.beginEvent(`ReactReconciler.updateComponent(${displayName})`); + }, + onUpdateComponent(debugID) { + Systrace.endEvent(); + }, + onBeforeUnmountComponent(debugID) { + const ReactComponentTreeHook = require('ReactGlobalSharedState').ReactComponentTreeHook; + const displayName = ReactComponentTreeHook.getDisplayName(debugID); + Systrace.beginEvent(`ReactReconciler.unmountComponent(${displayName})`); + }, + onUnmountComponent(debugID) { + Systrace.endEvent(); + }, + onBeginLifeCycleTimer(debugID, timerType) { + const ReactComponentTreeHook = require('ReactGlobalSharedState').ReactComponentTreeHook; + const displayName = ReactComponentTreeHook.getDisplayName(debugID); + Systrace.beginEvent(`${displayName}.${timerType}()`); + }, + onEndLifeCycleTimer(debugID, timerType) { + Systrace.endEvent(); + }, +}; + const Systrace = { - getUserTimingPolyfill() { - return userTimingPolyfill; + installReactHook(useFiber: boolean) { + if (_enabled) { + if (useFiber) { + global.performance = userTimingPolyfill; + } else { + require('ReactDebugTool').addHook(reactDebugToolHook); + } + } + _useFiber = useFiber; + _canInstallReactHook = true; }, setEnabled(enabled: boolean) { @@ -115,6 +161,18 @@ const Systrace = { } else { global.nativeTraceEndLegacy && global.nativeTraceEndLegacy(TRACE_TAG_JSC_CALLS); } + if (_canInstallReactHook) { + if (_useFiber) { + global.performance = enabled ? userTimingPolyfill : undefined; + } else { + const ReactDebugTool = require('ReactDebugTool'); + if (enabled) { + ReactDebugTool.addHook(reactDebugToolHook); + } else { + ReactDebugTool.removeHook(reactDebugToolHook); + } + } + } } _enabled = enabled; } diff --git a/Libraries/Renderer/shims/ReactNativeFeatureFlags.js b/Libraries/Renderer/shims/ReactNativeFeatureFlags.js index 1224b86f7..177198179 100644 --- a/Libraries/Renderer/shims/ReactNativeFeatureFlags.js +++ b/Libraries/Renderer/shims/ReactNativeFeatureFlags.js @@ -16,4 +16,8 @@ var ReactNativeFeatureFlags = { useFiber: false, }; +if (__DEV__) { + require('Systrace').installReactHook(false); +} + module.exports = ReactNativeFeatureFlags;