Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] [Not for Merge] Disable ReactPerf and Update Systrace React Integration #12797

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Libraries/Core/InitializeCore.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ if (!global.process.env.NODE_ENV) {
// Set up profile
const Systrace = require('Systrace');
Systrace.setEnabled(global.__RCTProfileIsProfiling || false);
if (__DEV__) {
global.performance = Systrace.getUserTimingPolyfill();
}

// Set up console
const ExceptionsManager = require('ExceptionsManager');
Expand Down
32 changes: 0 additions & 32 deletions Libraries/Performance/RCTRenderingPerf.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
*/
'use strict';

var ReactDebugTool = require('ReactDebugTool');
var ReactPerf = require('ReactPerf');

var invariant = require('fbjs/lib/invariant');
var performanceNow = require('fbjs/lib/performanceNow');

Expand All @@ -24,22 +21,6 @@ type perfModule = {

var perfModules = [];
var enabled = false;
var lastRenderStartTime = 0;
var totalRenderDuration = 0;

var RCTRenderingPerfDevtool = {
onBeginLifeCycleTimer(debugID, timerType) {
if (timerType === 'render') {
lastRenderStartTime = performanceNow();
}
},
onEndLifeCycleTimer(debugID, timerType) {
if (timerType === 'render') {
var lastRenderDuration = performanceNow() - lastRenderStartTime;
totalRenderDuration += lastRenderDuration;
}
},
};

var RCTRenderingPerf = {
// Once perf is enabled, it stays enabled
Expand All @@ -52,26 +33,13 @@ var RCTRenderingPerf = {
if (!enabled) {
return;
}

ReactPerf.start();
ReactDebugTool.addHook(RCTRenderingPerfDevtool);
perfModules.forEach((module) => module.start());
},

stop: function() {
if (!enabled) {
return;
}

ReactPerf.stop();
ReactPerf.printInclusive();
ReactPerf.printWasted();
ReactDebugTool.removeHook(RCTRenderingPerfDevtool);

console.log(`Total time spent in render(): ${totalRenderDuration.toFixed(2)} ms`);
lastRenderStartTime = 0;
totalRenderDuration = 0;

perfModules.forEach((module) => module.stop());
},

Expand Down
78 changes: 50 additions & 28 deletions Libraries/Performance/Systrace.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
*/
'use strict';

const invariant = require('invariant');

type RelayProfiler = {
attachProfileHandler(
name: string,
Expand All @@ -30,47 +32,67 @@ const TRACE_TAG_JSC_CALLS = 1 << 27;
let _enabled = false;
let _asyncCookie = 0;

const ReactSystraceDevtool = __DEV__ ? {
onBeforeMountComponent(debugID) {
const displayName = require('react/lib/ReactComponentTreeHook').getDisplayName(debugID);
Systrace.beginEvent(`ReactReconciler.mountComponent(${displayName})`);
},
onMountComponent(debugID) {
Systrace.endEvent();
},
onBeforeUpdateComponent(debugID) {
const displayName = require('react/lib/ReactComponentTreeHook').getDisplayName(debugID);
Systrace.beginEvent(`ReactReconciler.updateComponent(${displayName})`);
},
onUpdateComponent(debugID) {
Systrace.endEvent();
},
onBeforeUnmountComponent(debugID) {
const displayName = require('react/lib/ReactComponentTreeHook').getDisplayName(debugID);
Systrace.beginEvent(`ReactReconciler.unmountComponent(${displayName})`);
let _markStack = [];
let _markStackIndex = -1;

const userTimingPolyfill = {
mark(markName : string) {
if (__DEV__) {
if (_enabled) {
_markStackIndex++;
_markStack[_markStackIndex] = markName;
let label = markName;
if (markName[0] === '\u269B') {
// This is coming from React.
// Remove emoji and component IDs.
const indexOfId = markName.lastIndexOf(' (#');
const cutoffIndex = indexOfId !== -1 ? indexOfId : markName.length;
label = markName.slice(2, cutoffIndex);
}
Systrace.beginEvent(label);
}
}
},
onUnmountComponent(debugID) {
Systrace.endEvent();
measure(label : string, markName : string) {
if (__DEV__) {
if (_enabled) {
invariant(markName === _markStack[_markStackIndex], 'Unexpected measure() call.');
// TODO: it would be nice to use `label` because it is more friendly.
// I don't know if there's a way to annotate measurements post factum.
_markStackIndex--;
Systrace.endEvent();
}
}
},
onBeginLifeCycleTimer(debugID, timerType) {
const displayName = require('react/lib/ReactComponentTreeHook').getDisplayName(debugID);
Systrace.beginEvent(`${displayName}.${timerType}()`);
clearMarks(markName : string) {
if (__DEV__) {
if (_enabled) {
if (_markStackIndex > -1 && markName === _markStack[_markStackIndex]) {
_markStackIndex--;
// TODO: ideally this event shouldn't show up in the first place.
// I don't know if there's a way to cancel an ongoing measurement.
Systrace.endEvent();
}
}
}
},
onEndLifeCycleTimer(debugID, timerType) {
Systrace.endEvent();
clearMeasures() {
// Noop.
},
} : null;
};

const Systrace = {
getUserTimingPolyfill() {
return userTimingPolyfill;
},

setEnabled(enabled: boolean) {
if (_enabled !== enabled) {
if (__DEV__) {
if (enabled) {
global.nativeTraceBeginLegacy && global.nativeTraceBeginLegacy(TRACE_TAG_JSC_CALLS);
require('ReactDebugTool').addHook(ReactSystraceDevtool);
} else {
global.nativeTraceEndLegacy && global.nativeTraceEndLegacy(TRACE_TAG_JSC_CALLS);
require('ReactDebugTool').removeHook(ReactSystraceDevtool);
}
}
_enabled = enabled;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
*/
'use strict';

var ReactNative = require('ReactNative');
var ReactNativeAttributePayload = require('ReactNativeAttributePayload');
var TextInputState = require('TextInputState');
var UIManager = require('UIManager');
Expand Down Expand Up @@ -84,6 +83,7 @@ var NativeMethodsMixin = {
* prop](docs/view.html#onlayout) instead.
*/
measure: function(callback: MeasureOnSuccessCallback) {
var ReactNative = require('ReactNative');
UIManager.measure(
ReactNative.findNodeHandle(this),
mountSafeCallback(this, callback)
Expand All @@ -106,6 +106,7 @@ var NativeMethodsMixin = {
* has been completed in native.
*/
measureInWindow: function(callback: MeasureInWindowOnSuccessCallback) {
var ReactNative = require('ReactNative');
UIManager.measureInWindow(
ReactNative.findNodeHandle(this),
mountSafeCallback(this, callback)
Expand All @@ -125,6 +126,7 @@ var NativeMethodsMixin = {
onSuccess: MeasureLayoutOnSuccessCallback,
onFail: () => void /* currently unused */
) {
var ReactNative = require('ReactNative');
UIManager.measureLayout(
ReactNative.findNodeHandle(this),
relativeToNativeNode,
Expand All @@ -149,6 +151,7 @@ var NativeMethodsMixin = {
this.viewConfig.validAttributes
);

var ReactNative = require('ReactNative');
UIManager.updateView(
(ReactNative.findNodeHandle(this) : any),
this.viewConfig.uiViewClassName,
Expand All @@ -161,13 +164,15 @@ var NativeMethodsMixin = {
* will depend on the platform and type of view.
*/
focus: function() {
var ReactNative = require('ReactNative');
TextInputState.focusTextInput(ReactNative.findNodeHandle(this));
},

/**
* Removes focus from an input or view. This is the opposite of `focus()`.
*/
blur: function() {
var ReactNative = require('ReactNative');
TextInputState.blurTextInput(ReactNative.findNodeHandle(this));
},
};
Expand Down
2 changes: 1 addition & 1 deletion Libraries/Renderer/src/renderers/native/ReactNative.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
'use strict';

// TODO (bvaughn) Enable Fiber experiement via ReactNativeFeatureFlags
module.exports = require('ReactNativeStack');
module.exports = require('ReactNativeFiber');
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
'use strict';

var ReactNativeFeatureFlags = {
useFiber: false,
useFiber: true,
};

module.exports = ReactNativeFeatureFlags;
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* Copyright 2016-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
* @providesModule ReactFiberComponentTreeHook
*/

'use strict';

var ReactTypeOfWork = require('ReactTypeOfWork');
var {
IndeterminateComponent,
FunctionalComponent,
ClassComponent,
HostComponent,
} = ReactTypeOfWork;
var getComponentName = require('getComponentName');

import type { Fiber } from 'ReactFiber';

function describeComponentFrame(name, source: any, ownerName) {
return '\n in ' + (name || 'Unknown') + (
source ?
' (at ' + source.fileName.replace(/^.*[\\\/]/, '') + ':' +
source.lineNumber + ')' :
ownerName ?
' (created by ' + ownerName + ')' :
''
);
}

function describeFiber(fiber : Fiber) : string {
switch (fiber.tag) {
case IndeterminateComponent:
case FunctionalComponent:
case ClassComponent:
case HostComponent:
var owner = fiber._debugOwner;
var source = fiber._debugSource;
var name = getComponentName(fiber);
var ownerName = null;
if (owner) {
ownerName = getComponentName(owner);
}
return describeComponentFrame(name, source, ownerName);
default:
return '';
}
}

// This function can only be called with a work-in-progress fiber and
// only during begin or complete phase. Do not call it under any other
// circumstances.
function getStackAddendumByWorkInProgressFiber(workInProgress : Fiber) : string {
var info = '';
var node = workInProgress;
do {
info += describeFiber(node);
// Otherwise this return pointer might point to the wrong tree:
node = node.return;
} while (node);
return info;
}

module.exports = {
getStackAddendumByWorkInProgressFiber,
describeComponentFrame,
};
Loading