diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 51ad1a09a39..ccc7a91134c 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -2300,39 +2300,39 @@ public final class com/facebook/react/fabric/ComponentFactory { public fun ()V } -public class com/facebook/react/fabric/DevToolsReactPerfLogger : com/facebook/react/bridge/ReactMarker$FabricMarkerListener { +public final class com/facebook/react/fabric/DevToolsReactPerfLogger : com/facebook/react/bridge/ReactMarker$FabricMarkerListener { public fun ()V - public fun addDevToolsReactPerfLoggerListener (Lcom/facebook/react/fabric/DevToolsReactPerfLogger$DevToolsReactPerfLoggerListener;)V + public final fun addDevToolsReactPerfLoggerListener (Lcom/facebook/react/fabric/DevToolsReactPerfLogger$DevToolsReactPerfLoggerListener;)V public fun logFabricMarker (Lcom/facebook/react/bridge/ReactMarkerConstants;Ljava/lang/String;IJ)V public fun logFabricMarker (Lcom/facebook/react/bridge/ReactMarkerConstants;Ljava/lang/String;IJI)V - public fun removeDevToolsReactPerfLoggerListener (Lcom/facebook/react/fabric/DevToolsReactPerfLogger$DevToolsReactPerfLoggerListener;)V + public final fun removeDevToolsReactPerfLoggerListener (Lcom/facebook/react/fabric/DevToolsReactPerfLogger$DevToolsReactPerfLoggerListener;)V } public abstract interface class com/facebook/react/fabric/DevToolsReactPerfLogger$DevToolsReactPerfLoggerListener { public abstract fun onFabricCommitEnd (Lcom/facebook/react/fabric/DevToolsReactPerfLogger$FabricCommitPoint;)V } -public class com/facebook/react/fabric/DevToolsReactPerfLogger$FabricCommitPoint { - public fun getAffectedLayoutNodesCount ()I - public fun getAffectedLayoutNodesCountTime ()J - public fun getBatchExecutionDuration ()J - public fun getBatchExecutionEnd ()J - public fun getBatchExecutionStart ()J - public fun getCommitDuration ()J - public fun getCommitEnd ()J - public fun getCommitNumber ()J - public fun getCommitStart ()J - public fun getDiffDuration ()J - public fun getDiffEnd ()J - public fun getDiffStart ()J - public fun getFinishTransactionEnd ()J - public fun getFinishTransactionStart ()J - public fun getLayoutDuration ()J - public fun getLayoutEnd ()J - public fun getLayoutStart ()J - public fun getTransactionEndDuration ()J - public fun getUpdateUIMainThreadEnd ()J - public fun getUpdateUIMainThreadStart ()J +public final class com/facebook/react/fabric/DevToolsReactPerfLogger$FabricCommitPoint { + public final fun getAffectedLayoutNodesCount ()I + public final fun getAffectedLayoutNodesCountTime ()J + public final fun getBatchExecutionDuration ()J + public final fun getBatchExecutionEnd ()J + public final fun getBatchExecutionStart ()J + public final fun getCommitDuration ()J + public final fun getCommitEnd ()J + public final fun getCommitNumber ()J + public final fun getCommitStart ()J + public final fun getDiffDuration ()J + public final fun getDiffEnd ()J + public final fun getDiffStart ()J + public final fun getFinishTransactionEnd ()J + public final fun getFinishTransactionStart ()J + public final fun getLayoutDuration ()J + public final fun getLayoutEnd ()J + public final fun getLayoutStart ()J + public final fun getTransactionEndDuration ()J + public final fun getUpdateUIMainThreadEnd ()J + public final fun getUpdateUIMainThreadStart ()J public fun toString ()Ljava/lang/String; } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/DevToolsReactPerfLogger.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/DevToolsReactPerfLogger.java deleted file mode 100644 index b5539741304..00000000000 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/DevToolsReactPerfLogger.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.fabric; - -import static com.facebook.react.bridge.ReactMarkerConstants.FABRIC_BATCH_EXECUTION_END; -import static com.facebook.react.bridge.ReactMarkerConstants.FABRIC_BATCH_EXECUTION_START; -import static com.facebook.react.bridge.ReactMarkerConstants.FABRIC_COMMIT_END; -import static com.facebook.react.bridge.ReactMarkerConstants.FABRIC_COMMIT_START; -import static com.facebook.react.bridge.ReactMarkerConstants.FABRIC_DIFF_END; -import static com.facebook.react.bridge.ReactMarkerConstants.FABRIC_DIFF_START; -import static com.facebook.react.bridge.ReactMarkerConstants.FABRIC_FINISH_TRANSACTION_END; -import static com.facebook.react.bridge.ReactMarkerConstants.FABRIC_FINISH_TRANSACTION_START; -import static com.facebook.react.bridge.ReactMarkerConstants.FABRIC_LAYOUT_AFFECTED_NODES; -import static com.facebook.react.bridge.ReactMarkerConstants.FABRIC_LAYOUT_END; -import static com.facebook.react.bridge.ReactMarkerConstants.FABRIC_LAYOUT_START; -import static com.facebook.react.bridge.ReactMarkerConstants.FABRIC_UPDATE_UI_MAIN_THREAD_END; -import static com.facebook.react.bridge.ReactMarkerConstants.FABRIC_UPDATE_UI_MAIN_THREAD_START; - -import androidx.annotation.Nullable; -import com.facebook.infer.annotation.Nullsafe; -import com.facebook.react.bridge.ReactMarker; -import com.facebook.react.bridge.ReactMarkerConstants; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Nullsafe(Nullsafe.Mode.LOCAL) -public class DevToolsReactPerfLogger implements ReactMarker.FabricMarkerListener { - - private final Map mFabricCommitMarkers = new HashMap<>(); - private final List mDevToolsReactPerfLoggerListeners = - new ArrayList<>(); - - static final LongStreamingStats mStreamingCommitStats = new LongStreamingStats(); - static final LongStreamingStats mStreamingLayoutStats = new LongStreamingStats(); - static final LongStreamingStats mStreamingDiffStats = new LongStreamingStats(); - static final LongStreamingStats mStreamingTransactionEndStats = new LongStreamingStats(); - static final LongStreamingStats mStreamingBatchExecutionStats = new LongStreamingStats(); - - public interface DevToolsReactPerfLoggerListener { - void onFabricCommitEnd(FabricCommitPoint commitPoint); - } - - private static class FabricCommitPointData { - private final long mTimeStamp; - private final int mCounter; - - public FabricCommitPointData(long timeStamp, int counter) { - mTimeStamp = timeStamp; - mCounter = counter; - } - - public long getTimeStamp() { - return mTimeStamp; - } - - public int getCounter() { - return mCounter; - } - } - - public static class FabricCommitPoint { - private final long mCommitNumber; - private final Map mPoints = new HashMap<>(); - - private FabricCommitPoint(int commitNumber) { - mCommitNumber = commitNumber; - } - - private void addPoint(ReactMarkerConstants key, FabricCommitPointData data) { - mPoints.put(key, data); - } - - private long getTimestamp(ReactMarkerConstants marker) { - FabricCommitPointData data = mPoints.get(marker); - return data != null ? data.getTimeStamp() : -1; - } - - private int getCounter(ReactMarkerConstants marker) { - FabricCommitPointData data = mPoints.get(marker); - return data != null ? data.getCounter() : 0; - } - - public long getCommitNumber() { - return mCommitNumber; - } - - public long getCommitStart() { - return getTimestamp(FABRIC_COMMIT_START); - } - - public long getCommitEnd() { - return getTimestamp(FABRIC_COMMIT_END); - } - - public long getFinishTransactionStart() { - return getTimestamp(FABRIC_FINISH_TRANSACTION_START); - } - - public long getFinishTransactionEnd() { - return getTimestamp(FABRIC_FINISH_TRANSACTION_END); - } - - public long getDiffStart() { - return getTimestamp(FABRIC_DIFF_START); - } - - public long getDiffEnd() { - return getTimestamp(FABRIC_DIFF_END); - } - - public long getLayoutStart() { - return getTimestamp(FABRIC_LAYOUT_START); - } - - public long getLayoutEnd() { - return getTimestamp(FABRIC_LAYOUT_END); - } - - public int getAffectedLayoutNodesCount() { - return getCounter(FABRIC_LAYOUT_AFFECTED_NODES); - } - - public long getAffectedLayoutNodesCountTime() { - return getTimestamp(FABRIC_LAYOUT_AFFECTED_NODES); - } - - public long getBatchExecutionStart() { - return getTimestamp(FABRIC_BATCH_EXECUTION_START); - } - - public long getBatchExecutionEnd() { - return getTimestamp(FABRIC_BATCH_EXECUTION_END); - } - - public long getUpdateUIMainThreadStart() { - return getTimestamp(FABRIC_UPDATE_UI_MAIN_THREAD_START); - } - - public long getUpdateUIMainThreadEnd() { - return getTimestamp(FABRIC_UPDATE_UI_MAIN_THREAD_END); - } - - // Duration calculations - public long getCommitDuration() { - return getCommitEnd() - getCommitStart(); - } - - public long getLayoutDuration() { - return getLayoutEnd() - getLayoutStart(); - } - - public long getDiffDuration() { - return getDiffEnd() - getDiffStart(); - } - - public long getTransactionEndDuration() { - return getFinishTransactionEnd() - getFinishTransactionStart(); - } - - public long getBatchExecutionDuration() { - return getBatchExecutionEnd() - getBatchExecutionStart(); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder("FabricCommitPoint{"); - builder.append("mCommitNumber=").append(mCommitNumber); - builder.append(", mPoints=").append(mPoints); - builder.append('}'); - return builder.toString(); - } - } - - public void addDevToolsReactPerfLoggerListener(DevToolsReactPerfLoggerListener listener) { - mDevToolsReactPerfLoggerListeners.add(listener); - } - - public void removeDevToolsReactPerfLoggerListener(DevToolsReactPerfLoggerListener listener) { - mDevToolsReactPerfLoggerListeners.remove(listener); - } - - @Override - public void logFabricMarker( - ReactMarkerConstants name, @Nullable String tag, int instanceKey, long timestamp) { - logFabricMarker(name, tag, instanceKey, timestamp, 0); - } - - @Override - public void logFabricMarker( - ReactMarkerConstants name, - @Nullable String tag, - int instanceKey, - long timestamp, - int counter) { - - if (isFabricCommitMarker(name)) { - FabricCommitPoint commitPoint = mFabricCommitMarkers.get(instanceKey); - if (commitPoint == null) { - commitPoint = new FabricCommitPoint(instanceKey); - mFabricCommitMarkers.put(instanceKey, commitPoint); - } - commitPoint.addPoint(name, new FabricCommitPointData(timestamp, counter)); - - if (name == ReactMarkerConstants.FABRIC_BATCH_EXECUTION_END && timestamp > 0) { - onFabricCommitEnd(commitPoint); - mFabricCommitMarkers.remove(instanceKey); - } - } - } - - private void onFabricCommitEnd(FabricCommitPoint commitPoint) { - for (DevToolsReactPerfLoggerListener listener : mDevToolsReactPerfLoggerListeners) { - listener.onFabricCommitEnd(commitPoint); - } - } - - private static boolean isFabricCommitMarker(ReactMarkerConstants name) { - return name == FABRIC_COMMIT_START - || name == FABRIC_COMMIT_END - || name == FABRIC_FINISH_TRANSACTION_START - || name == FABRIC_FINISH_TRANSACTION_END - || name == FABRIC_DIFF_START - || name == FABRIC_DIFF_END - || name == FABRIC_LAYOUT_START - || name == FABRIC_LAYOUT_END - || name == FABRIC_BATCH_EXECUTION_START - || name == FABRIC_BATCH_EXECUTION_END - || name == FABRIC_UPDATE_UI_MAIN_THREAD_START - || name == FABRIC_UPDATE_UI_MAIN_THREAD_END - || name == FABRIC_LAYOUT_AFFECTED_NODES; - } -} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/DevToolsReactPerfLogger.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/DevToolsReactPerfLogger.kt new file mode 100644 index 00000000000..d19987090db --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/DevToolsReactPerfLogger.kt @@ -0,0 +1,176 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.fabric + +import com.facebook.react.bridge.ReactMarker.FabricMarkerListener +import com.facebook.react.bridge.ReactMarkerConstants +import kotlin.jvm.JvmField + +public class DevToolsReactPerfLogger : FabricMarkerListener { + + private val fabricCommitMarkers = mutableMapOf() + private val devToolsReactPerfLoggerListeners = mutableListOf() + + public fun interface DevToolsReactPerfLoggerListener { + public fun onFabricCommitEnd(commitPoint: FabricCommitPoint) + } + + internal class FabricCommitPointData(val timeStamp: Long, val counter: Int) + + public class FabricCommitPoint internal constructor(commitNumber: Int) { + public val commitNumber: Long = commitNumber.toLong() + private val points = mutableMapOf() + + internal fun addPoint(key: ReactMarkerConstants, data: FabricCommitPointData) { + points[key] = data + } + + private fun getTimestamp(marker: ReactMarkerConstants): Long { + val data = points[marker] + return data?.timeStamp ?: -1 + } + + private fun getCounter(marker: ReactMarkerConstants): Int = points[marker]?.counter ?: 0 + + public val commitStart: Long + get() = getTimestamp(ReactMarkerConstants.FABRIC_COMMIT_START) + + public val commitEnd: Long + get() = getTimestamp(ReactMarkerConstants.FABRIC_COMMIT_END) + + public val finishTransactionStart: Long + get() = getTimestamp(ReactMarkerConstants.FABRIC_FINISH_TRANSACTION_START) + + public val finishTransactionEnd: Long + get() = getTimestamp(ReactMarkerConstants.FABRIC_FINISH_TRANSACTION_END) + + public val diffStart: Long + get() = getTimestamp(ReactMarkerConstants.FABRIC_DIFF_START) + + public val diffEnd: Long + get() = getTimestamp(ReactMarkerConstants.FABRIC_DIFF_END) + + public val layoutStart: Long + get() = getTimestamp(ReactMarkerConstants.FABRIC_LAYOUT_START) + + public val layoutEnd: Long + get() = getTimestamp(ReactMarkerConstants.FABRIC_LAYOUT_END) + + public val affectedLayoutNodesCount: Int + get() = getCounter(ReactMarkerConstants.FABRIC_LAYOUT_AFFECTED_NODES) + + public val affectedLayoutNodesCountTime: Long + get() = getTimestamp(ReactMarkerConstants.FABRIC_LAYOUT_AFFECTED_NODES) + + public val batchExecutionStart: Long + get() = getTimestamp(ReactMarkerConstants.FABRIC_BATCH_EXECUTION_START) + + public val batchExecutionEnd: Long + get() = getTimestamp(ReactMarkerConstants.FABRIC_BATCH_EXECUTION_END) + + public val updateUIMainThreadStart: Long + get() = getTimestamp(ReactMarkerConstants.FABRIC_UPDATE_UI_MAIN_THREAD_START) + + public val updateUIMainThreadEnd: Long + get() = getTimestamp(ReactMarkerConstants.FABRIC_UPDATE_UI_MAIN_THREAD_END) + + public val commitDuration: Long + // Duration calculations + get() = commitEnd - commitStart + + public val layoutDuration: Long + get() = layoutEnd - layoutStart + + public val diffDuration: Long + get() = diffEnd - diffStart + + public val transactionEndDuration: Long + get() = finishTransactionEnd - finishTransactionStart + + public val batchExecutionDuration: Long + get() = batchExecutionEnd - batchExecutionStart + + override fun toString(): String { + return "FabricCommitPoint{mCommitNumber=$commitNumber, mPoints=$points}" + } + } + + public fun addDevToolsReactPerfLoggerListener(listener: DevToolsReactPerfLoggerListener): Unit { + devToolsReactPerfLoggerListeners.add(listener) + } + + public fun removeDevToolsReactPerfLoggerListener( + listener: DevToolsReactPerfLoggerListener + ): Unit { + devToolsReactPerfLoggerListeners.remove(listener) + } + + override fun logFabricMarker( + name: ReactMarkerConstants, + tag: String?, + instanceKey: Int, + timestamp: Long + ) { + logFabricMarker(name, tag, instanceKey, timestamp, 0) + } + + override fun logFabricMarker( + name: ReactMarkerConstants, + tag: String?, + instanceKey: Int, + timestamp: Long, + counter: Int + ) { + if (isFabricCommitMarker(name)) { + var commitPoint = fabricCommitMarkers[instanceKey] + if (commitPoint == null) { + commitPoint = FabricCommitPoint(instanceKey) + fabricCommitMarkers[instanceKey] = commitPoint + } + commitPoint.addPoint(name, FabricCommitPointData(timestamp, counter)) + + if (name == ReactMarkerConstants.FABRIC_BATCH_EXECUTION_END && timestamp > 0) { + onFabricCommitEnd(commitPoint) + fabricCommitMarkers.remove(instanceKey) + } + } + } + + private fun onFabricCommitEnd(commitPoint: FabricCommitPoint) { + for (listener in devToolsReactPerfLoggerListeners) { + listener.onFabricCommitEnd(commitPoint) + } + } + + private companion object { + @JvmField internal val streamingCommitStats: LongStreamingStats = LongStreamingStats() + + @JvmField internal val streamingLayoutStats: LongStreamingStats = LongStreamingStats() + + @JvmField internal val streamingDiffStats: LongStreamingStats = LongStreamingStats() + + @JvmField internal val streamingTransactionEndStats: LongStreamingStats = LongStreamingStats() + + @JvmField internal val streamingBatchExecutionStats: LongStreamingStats = LongStreamingStats() + + private fun isFabricCommitMarker(name: ReactMarkerConstants): Boolean = + name == ReactMarkerConstants.FABRIC_COMMIT_START || + name == ReactMarkerConstants.FABRIC_COMMIT_END || + name == ReactMarkerConstants.FABRIC_FINISH_TRANSACTION_START || + name == ReactMarkerConstants.FABRIC_FINISH_TRANSACTION_END || + name == ReactMarkerConstants.FABRIC_DIFF_START || + name == ReactMarkerConstants.FABRIC_DIFF_END || + name == ReactMarkerConstants.FABRIC_LAYOUT_START || + name == ReactMarkerConstants.FABRIC_LAYOUT_END || + name == ReactMarkerConstants.FABRIC_BATCH_EXECUTION_START || + name == ReactMarkerConstants.FABRIC_BATCH_EXECUTION_END || + name == ReactMarkerConstants.FABRIC_UPDATE_UI_MAIN_THREAD_START || + name == ReactMarkerConstants.FABRIC_UPDATE_UI_MAIN_THREAD_END || + name == ReactMarkerConstants.FABRIC_LAYOUT_AFFECTED_NODES + } +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index b62625bb171..8e0c683e158 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -119,11 +119,11 @@ public class FabricUIManager long transactionEndDuration = commitPoint.getTransactionEndDuration(); long batchExecutionDuration = commitPoint.getBatchExecutionDuration(); - DevToolsReactPerfLogger.mStreamingCommitStats.add(commitDuration); - DevToolsReactPerfLogger.mStreamingLayoutStats.add(layoutDuration); - DevToolsReactPerfLogger.mStreamingDiffStats.add(diffDuration); - DevToolsReactPerfLogger.mStreamingTransactionEndStats.add(transactionEndDuration); - DevToolsReactPerfLogger.mStreamingBatchExecutionStats.add(batchExecutionDuration); + DevToolsReactPerfLogger.streamingCommitStats.add(commitDuration); + DevToolsReactPerfLogger.streamingLayoutStats.add(layoutDuration); + DevToolsReactPerfLogger.streamingDiffStats.add(diffDuration); + DevToolsReactPerfLogger.streamingTransactionEndStats.add(transactionEndDuration); + DevToolsReactPerfLogger.streamingBatchExecutionStats.add(batchExecutionDuration); FLog.i( TAG, @@ -136,25 +136,25 @@ public class FabricUIManager + " - Mounting: %d ms. Avg: %.2f. Median: %.2f ms. Max: %d ms.\n", commitPoint.getCommitNumber(), commitDuration, - DevToolsReactPerfLogger.mStreamingCommitStats.getAverage(), - DevToolsReactPerfLogger.mStreamingCommitStats.getMedian(), - DevToolsReactPerfLogger.mStreamingCommitStats.getMax(), + DevToolsReactPerfLogger.streamingCommitStats.getAverage(), + DevToolsReactPerfLogger.streamingCommitStats.getMedian(), + DevToolsReactPerfLogger.streamingCommitStats.getMax(), layoutDuration, - DevToolsReactPerfLogger.mStreamingLayoutStats.getAverage(), - DevToolsReactPerfLogger.mStreamingLayoutStats.getMedian(), - DevToolsReactPerfLogger.mStreamingLayoutStats.getMax(), + DevToolsReactPerfLogger.streamingLayoutStats.getAverage(), + DevToolsReactPerfLogger.streamingLayoutStats.getMedian(), + DevToolsReactPerfLogger.streamingLayoutStats.getMax(), diffDuration, - DevToolsReactPerfLogger.mStreamingDiffStats.getAverage(), - DevToolsReactPerfLogger.mStreamingDiffStats.getMedian(), - DevToolsReactPerfLogger.mStreamingDiffStats.getMax(), + DevToolsReactPerfLogger.streamingDiffStats.getAverage(), + DevToolsReactPerfLogger.streamingDiffStats.getMedian(), + DevToolsReactPerfLogger.streamingDiffStats.getMax(), transactionEndDuration, - DevToolsReactPerfLogger.mStreamingTransactionEndStats.getAverage(), - DevToolsReactPerfLogger.mStreamingTransactionEndStats.getMedian(), - DevToolsReactPerfLogger.mStreamingTransactionEndStats.getMax(), + DevToolsReactPerfLogger.streamingTransactionEndStats.getAverage(), + DevToolsReactPerfLogger.streamingTransactionEndStats.getMedian(), + DevToolsReactPerfLogger.streamingTransactionEndStats.getMax(), batchExecutionDuration, - DevToolsReactPerfLogger.mStreamingBatchExecutionStats.getAverage(), - DevToolsReactPerfLogger.mStreamingBatchExecutionStats.getMedian(), - DevToolsReactPerfLogger.mStreamingBatchExecutionStats.getMax()); + DevToolsReactPerfLogger.streamingBatchExecutionStats.getAverage(), + DevToolsReactPerfLogger.streamingBatchExecutionStats.getMedian(), + DevToolsReactPerfLogger.streamingBatchExecutionStats.getMax()); }; static {