diff --git a/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js b/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js index ce1e56cfa..fde1f06c1 100644 --- a/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js +++ b/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js @@ -133,7 +133,9 @@ function setUpWebSockets() { function setupProfile() { console.profile = console.profile || GLOBAL.nativeTraceBeginSection || function () {}; console.profileEnd = console.profileEnd || GLOBAL.nativeTraceEndSection || function () {}; - require('BridgeProfiling').swizzleReactPerf(); + if (__DEV__) { + require('BridgeProfiling').swizzleReactPerf(); + } } function setUpProcessEnv() { diff --git a/Libraries/Utilities/BridgeProfiling.js b/Libraries/Utilities/BridgeProfiling.js index 94ff3b3c6..8ff7583cd 100644 --- a/Libraries/Utilities/BridgeProfiling.js +++ b/Libraries/Utilities/BridgeProfiling.js @@ -14,9 +14,24 @@ var GLOBAL = GLOBAL || this; var TRACE_TAG_REACT_APPS = 1 << 17; +var _enabled = false; +var _ReactPerf = null; +function ReactPerf() { + if (!_ReactPerf) { + _ReactPerf = require('ReactPerf'); + } + return _ReactPerf; +} + var BridgeProfiling = { + setEnabled(enabled: boolean) { + _enabled = enabled; + + ReactPerf().enableMeasure = enabled; + }, + profile(profileName?: any) { - if (GLOBAL.__BridgeProfilingIsProfiling) { + if (_enabled) { profileName = typeof profileName === 'function' ? profileName() : profileName; console.profile(TRACE_TAG_REACT_APPS, profileName); @@ -24,29 +39,28 @@ var BridgeProfiling = { }, profileEnd() { - if (GLOBAL.__BridgeProfilingIsProfiling) { + if (_enabled) { console.profileEnd(TRACE_TAG_REACT_APPS); } }, - swizzleReactPerf() { - var ReactPerf = require('ReactPerf'); - var originalMeasure = ReactPerf.measure; - ReactPerf.measure = function (objName, fnName, func) { - func = originalMeasure.apply(ReactPerf, arguments); - return function (component) { - if (GLOBAL.__BridgeProfilingIsProfiling) { - var name = this._instance && this._instance.constructor && - (this._instance.constructor.displayName || - this._instance.constructor.name); - BridgeProfiling.profile(`${objName}.${fnName}(${name})`); - } - var ret = func.apply(this, arguments); - BridgeProfiling.profileEnd(); - return ret; - }; + reactPerfMeasure(objName: string, fnName: string, func: any): any { + return function (component) { + if (!_enabled) { + return func.apply(this, arguments); + } + + var name = objName === 'ReactCompositeComponent' && this.getName() || ''; + BridgeProfiling.profile(`${objName}.${fnName}(${name})`); + var ret = func.apply(this, arguments); + BridgeProfiling.profileEnd(); + return ret; }; }, + + swizzleReactPerf() { + ReactPerf().injection.injectMeasure(BridgeProfiling.reactPerfMeasure); + }, }; module.exports = BridgeProfiling; diff --git a/React/Executors/RCTContextExecutor.m b/React/Executors/RCTContextExecutor.m index 971d10111..4781e72de 100644 --- a/React/Executors/RCTContextExecutor.m +++ b/React/Executors/RCTContextExecutor.m @@ -336,17 +336,13 @@ static void RCTInstallJSCProfiler(RCTBridge *bridge, JSContextRef context) - (void)toggleProfilingFlag:(NSNotification *)notification { - JSObjectRef globalObject = JSContextGetGlobalObject(_context.ctx); - - bool enabled = [notification.name isEqualToString:RCTProfileDidStartProfiling]; - JSStringRef JSName = JSStringCreateWithUTF8CString("__BridgeProfilingIsProfiling"); - JSObjectSetProperty(_context.ctx, - globalObject, - JSName, - JSValueMakeBoolean(_context.ctx, enabled), - kJSPropertyAttributeNone, - NULL); - JSStringRelease(JSName); + [self executeBlockOnJavaScriptQueue:^{ + BOOL enabled = [notification.name isEqualToString:RCTProfileDidStartProfiling]; + NSString *script = [NSString stringWithFormat:@"var p = require('BridgeProfiling') || {}; p.setEnabled && p.setEnabled(%@)", enabled ? @"true" : @"false"]; + JSStringRef scriptJSRef = JSStringCreateWithUTF8CString(script.UTF8String); + JSEvaluateScript(_context.ctx, scriptJSRef, NULL, NULL, 0, NULL); + JSStringRelease(scriptJSRef); + }]; } - (void)_addNativeHook:(JSObjectCallAsFunctionCallback)hook withName:(const char *)name