mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add performance counters for Fabric
Summary: This diff adds performance loggers for Fabric in Android to be able to compare current version or RN with Fabric This is the summary of Points and Annotations: - **UIManager_CommitStart**: time that React starts the commit (react tree is ready to start rendering in native) - **UIManager_LayoutTime**: this is the time it takes to calculate layout in yoga - **UIManager_FabricFinishTransactionTime**: Time it takes transform "C++ mutationInstructions" into "Java MountItems" and cross boundaries from C++ to Java (including serialization of data) (THIS IS ONLY FABRIC) - **UIManager_DispatchViewUpdates**: time right before RN moves the mount operations to the Queue that is going to be processed in the next tick UI thread - **UIManager_BatchRunStart**: time right before the mountItems are going to be process in the UI Thread - **UIManager_BatchedExecutionTime**: time it took to run batched mountItems (usually layout and prop updates on views) - **UIManager_NonBatchedExecutionTime**: time it took to run non-batched mountItems (usually creation of views) Reviewed By: fkgozali Differential Revision: D13838337 fbshipit-source-id: 0a707619829e7d95ce94d9305ff434d1224afc46
This commit is contained in:
committed by
Facebook Github Bot
parent
c493cfe708
commit
7f27888878
@@ -6,18 +6,33 @@
|
||||
*/
|
||||
package com.facebook.react.fabric;
|
||||
|
||||
import static com.facebook.infer.annotation.ThreadConfined.UI;
|
||||
import static com.facebook.react.fabric.mounting.LayoutMetricsConversions.getMaxSize;
|
||||
import static com.facebook.react.fabric.mounting.LayoutMetricsConversions.getMinSize;
|
||||
import static com.facebook.react.fabric.mounting.LayoutMetricsConversions.getYogaMeasureMode;
|
||||
import static com.facebook.react.fabric.mounting.LayoutMetricsConversions.getYogaSize;
|
||||
import static com.facebook.infer.annotation.ThreadConfined.UI;
|
||||
import static com.facebook.react.uimanager.common.UIManagerType.FABRIC;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.SystemClock;
|
||||
import android.support.annotation.GuardedBy;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.infer.annotation.ThreadConfined;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.bridge.GuardedRunnable;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.NativeMap;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableNativeMap;
|
||||
import com.facebook.react.bridge.UIManager;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.fabric.jsi.Binding;
|
||||
import com.facebook.react.fabric.jsi.EventBeatManager;
|
||||
import com.facebook.react.fabric.jsi.EventEmitterWrapper;
|
||||
@@ -35,20 +50,6 @@ import com.facebook.react.fabric.mounting.mountitems.UpdateEventEmitterMountItem
|
||||
import com.facebook.react.fabric.mounting.mountitems.UpdateLayoutMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.UpdateLocalDataMountItem;
|
||||
import com.facebook.react.fabric.mounting.mountitems.UpdatePropsMountItem;
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
import com.facebook.infer.annotation.ThreadConfined;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.bridge.GuardedRunnable;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.NativeMap;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableNativeMap;
|
||||
import com.facebook.react.bridge.UIManager;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.modules.core.ReactChoreographer;
|
||||
import com.facebook.react.uimanager.IllegalViewOperationException;
|
||||
import com.facebook.react.uimanager.ReactRootViewTagGenerator;
|
||||
@@ -109,6 +110,13 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
|
||||
@ThreadConfined(UI)
|
||||
private boolean mIsMountingEnabled = true;
|
||||
private long mRunStartTime = 0l;
|
||||
private long mBatchedExecutionTime = 0l;
|
||||
private long mNonBatchedExecutionTime = 0l;
|
||||
private long mDispatchViewUpdatesTime = 0l;
|
||||
private long mCommitStartTime = 0l;
|
||||
private long mLayoutTime = 0l;
|
||||
private long mFinishTransactionTime = 0l;
|
||||
|
||||
public FabricUIManager(
|
||||
ReactApplicationContext reactContext,
|
||||
@@ -268,7 +276,17 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
*/
|
||||
@DoNotStrip
|
||||
@SuppressWarnings("unused")
|
||||
private void scheduleMountItems(final MountItem mountItems) {
|
||||
private void scheduleMountItems(
|
||||
final MountItem mountItems,
|
||||
long commitStartTime,
|
||||
long layoutTime,
|
||||
long finishTransactionStartTime) {
|
||||
|
||||
// TODO T31905686: support multithreading
|
||||
mCommitStartTime = commitStartTime;
|
||||
mLayoutTime = layoutTime;
|
||||
mFinishTransactionTime = SystemClock.uptimeMillis() - finishTransactionStartTime;
|
||||
mDispatchViewUpdatesTime = SystemClock.uptimeMillis();
|
||||
synchronized (mMountItemsLock) {
|
||||
mMountItems.add(mountItems);
|
||||
}
|
||||
@@ -294,26 +312,32 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
mPreMountItems = new ArrayList<>();
|
||||
}
|
||||
|
||||
mRunStartTime = SystemClock.uptimeMillis();
|
||||
List<MountItem> mountItemsToDispatch;
|
||||
synchronized (mMountItemsLock) {
|
||||
mountItemsToDispatch = mMountItems;
|
||||
mMountItems = new ArrayList<>();
|
||||
}
|
||||
|
||||
long nonBatchedExecutionStartTime = SystemClock.uptimeMillis();
|
||||
Systrace.beginSection(
|
||||
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
|
||||
"FabricUIManager::premountViews (" + preMountItemsToDispatch.size() + " batches)");
|
||||
for (MountItem mountItem : preMountItemsToDispatch) {
|
||||
mountItem.execute(mMountingManager);
|
||||
}
|
||||
mNonBatchedExecutionTime = SystemClock.uptimeMillis() - nonBatchedExecutionStartTime;
|
||||
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||
|
||||
Systrace.beginSection(
|
||||
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
|
||||
"FabricUIManager::mountViews (" + mountItemsToDispatch.size() + " batches)");
|
||||
|
||||
long batchedExecutionStartTime = SystemClock.uptimeMillis();
|
||||
for (MountItem mountItem : mountItemsToDispatch) {
|
||||
mountItem.execute(mMountingManager);
|
||||
}
|
||||
mBatchedExecutionTime = SystemClock.uptimeMillis() - batchedExecutionStartTime;
|
||||
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||
} catch (Exception ex) {
|
||||
FLog.e(ReactConstants.TAG, "Exception thrown when executing UIFrameGuarded", ex);
|
||||
@@ -379,7 +403,9 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
@Override
|
||||
public void dispatchCommand(
|
||||
final int reactTag, final int commandId, final ReadableArray commandArgs) {
|
||||
scheduleMountItems(new DispatchCommandMountItem(reactTag, commandId, commandArgs));
|
||||
synchronized (mMountItemsLock) {
|
||||
mMountItems.add(new DispatchCommandMountItem(reactTag, commandId, commandArgs));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -394,12 +420,20 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
|
||||
@Override
|
||||
public void profileNextBatch() {
|
||||
// do nothing for now.
|
||||
// TODO T31905686: Remove this method and add support for multi-threading performance counters
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Long> getPerformanceCounters() {
|
||||
return new HashMap<>();
|
||||
HashMap<String, Long> performanceCounters = new HashMap<>();
|
||||
performanceCounters.put("CommitStartTime", mCommitStartTime);
|
||||
performanceCounters.put("LayoutTime", mLayoutTime);
|
||||
performanceCounters.put("DispatchViewUpdatesTime", mDispatchViewUpdatesTime);
|
||||
performanceCounters.put("RunStartTime", mRunStartTime);
|
||||
performanceCounters.put("BatchedExecutionTime", mBatchedExecutionTime);
|
||||
performanceCounters.put("NonBatchedExecutionTime", mNonBatchedExecutionTime);
|
||||
performanceCounters.put("FinishFabricTransactionTime", mFinishTransactionTime);
|
||||
return performanceCounters;
|
||||
}
|
||||
|
||||
private class DispatchUIFrameCallback extends GuardedFrameCallback {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <react/uimanager/primitives.h>
|
||||
#include <react/uimanager/Scheduler.h>
|
||||
#include <react/uimanager/SchedulerDelegate.h>
|
||||
#include <react/uimanager/TimeUtils.h>
|
||||
|
||||
using namespace facebook::jni;
|
||||
using namespace facebook::jsi;
|
||||
@@ -249,12 +250,15 @@ local_ref<JMountItem::javaobject> createDeleteMountItem(const jni::global_ref<jo
|
||||
return deleteInstruction(javaUIManager, mutation.oldChildShadowView.tag);
|
||||
}
|
||||
|
||||
void Binding::schedulerDidFinishTransaction(const Tag rootTag, const ShadowViewMutationList &mutations) {
|
||||
void Binding::schedulerDidFinishTransaction(const Tag rootTag, const ShadowViewMutationList &mutations, const long commitStartTime, const long layoutTime) {
|
||||
SystraceSection s("FabricUIManager::schedulerDidFinishTransaction");
|
||||
std::vector<local_ref<jobject>> queue;
|
||||
// Upper bound estimation of mount items to be delivered to Java side.
|
||||
int size = mutations.size() * 3 + 42;
|
||||
|
||||
long finishTransactionStartTime = getTime();
|
||||
|
||||
|
||||
local_ref<JArrayClass<JMountItem::javaobject>> mountItemsArray = JArrayClass<JMountItem::javaobject>::newArray(size);
|
||||
|
||||
auto mountItems = *(mountItemsArray);
|
||||
@@ -341,9 +345,9 @@ void Binding::schedulerDidFinishTransaction(const Tag rootTag, const ShadowViewM
|
||||
|
||||
static auto scheduleMountItems =
|
||||
jni::findClassStatic(UIManagerJavaDescriptor)
|
||||
->getMethod<void(JMountItem::javaobject)>("scheduleMountItems");
|
||||
->getMethod<void(JMountItem::javaobject,jlong,jlong,jlong)>("scheduleMountItems");
|
||||
|
||||
scheduleMountItems(javaUIManager_, batch.get());
|
||||
scheduleMountItems(javaUIManager_, batch.get(), commitStartTime, layoutTime, finishTransactionStartTime);
|
||||
}
|
||||
|
||||
void Binding::setPixelDensity(float pointScaleFactor) {
|
||||
|
||||
@@ -46,7 +46,7 @@ private:
|
||||
|
||||
void stopSurface(jint surfaceId);
|
||||
|
||||
void schedulerDidFinishTransaction(const Tag rootTag, const ShadowViewMutationList &mutations);
|
||||
void schedulerDidFinishTransaction(const Tag rootTag, const ShadowViewMutationList &mutations, const long commitStartTime, const long layoutTime);
|
||||
|
||||
void schedulerDidRequestPreliminaryViewAllocation(const SurfaceId surfaceId, const ComponentName componentName, bool isLayoutable, const ComponentHandle componentHandle);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user