mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Maintain a separate queue for ViewCommands and execute before everything else
Summary: ViewCommands are sort of like setNativeProps updates, in that they're direct manipulations of Views on-screen that don't go through the normal commit/diff process that other UI updates do. This is an MVP that shows how we can do this in non-Fabric RN. Changelog: [Internal] experiment, allow ViewCommands to be executed before other types of UIOperations Reviewed By: axe-fb, mdvacca Differential Revision: D20378633 fbshipit-source-id: 5f3c54d3c84b4e4f7cb060a9505b20b0e5b7afed
This commit is contained in:
committed by
Facebook Github Bot
parent
99ceb6afba
commit
8b61578076
@@ -79,6 +79,12 @@ public class ReactFeatureFlags {
|
||||
*/
|
||||
public static boolean allowDisablingImmediateExecutionOfScheduleMountItems = false;
|
||||
|
||||
/**
|
||||
* Temporary flag. See UIImplementation: if this flag is enabled, ViewCommands will be queued and
|
||||
* executed before any other types of UI operations.
|
||||
*/
|
||||
public static boolean allowEarlyViewCommandExecution = false;
|
||||
|
||||
/**
|
||||
* This react flag enables a custom algorithm for the getChildVisibleRect() method in the classes
|
||||
* ReactViewGroup, ReactHorizontalScrollView and ReactScrollView.
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.SoftAssertions;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.react.modules.core.ReactChoreographer;
|
||||
import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugListener;
|
||||
import com.facebook.systrace.Systrace;
|
||||
@@ -518,6 +519,9 @@ public class UIViewOperationQueue {
|
||||
private final DispatchUIFrameCallback mDispatchUIFrameCallback;
|
||||
private final ReactApplicationContext mReactApplicationContext;
|
||||
|
||||
private final boolean mAllowViewCommandsQueue;
|
||||
private ArrayList<UIOperation> mViewCommandOperations = new ArrayList<>();
|
||||
|
||||
// Only called from the UIManager queue?
|
||||
private ArrayList<UIOperation> mOperations = new ArrayList<>();
|
||||
|
||||
@@ -556,6 +560,7 @@ public class UIViewOperationQueue {
|
||||
? DEFAULT_MIN_TIME_LEFT_IN_FRAME_FOR_NONBATCHED_OPERATION_MS
|
||||
: minTimeLeftInFrameForNonBatchedOperationMs);
|
||||
mReactApplicationContext = reactContext;
|
||||
mAllowViewCommandsQueue = ReactFeatureFlags.allowEarlyViewCommandExecution;
|
||||
}
|
||||
|
||||
/*package*/ NativeViewHierarchyManager getNativeViewHierarchyManager() {
|
||||
@@ -591,7 +596,7 @@ public class UIViewOperationQueue {
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return mOperations.isEmpty();
|
||||
return mOperations.isEmpty() && mViewCommandOperations.isEmpty();
|
||||
}
|
||||
|
||||
public void addRootView(final int tag, final View rootView) {
|
||||
@@ -625,12 +630,24 @@ public class UIViewOperationQueue {
|
||||
@Deprecated
|
||||
public void enqueueDispatchCommand(
|
||||
int reactTag, int commandId, @Nullable ReadableArray commandArgs) {
|
||||
mOperations.add(new DispatchCommandOperation(reactTag, commandId, commandArgs));
|
||||
final DispatchCommandOperation command =
|
||||
new DispatchCommandOperation(reactTag, commandId, commandArgs);
|
||||
if (mAllowViewCommandsQueue) {
|
||||
mViewCommandOperations.add(command);
|
||||
} else {
|
||||
mOperations.add(command);
|
||||
}
|
||||
}
|
||||
|
||||
public void enqueueDispatchCommand(
|
||||
int reactTag, String commandId, @Nullable ReadableArray commandArgs) {
|
||||
mOperations.add(new DispatchStringCommandOperation(reactTag, commandId, commandArgs));
|
||||
final DispatchStringCommandOperation command =
|
||||
new DispatchStringCommandOperation(reactTag, commandId, commandArgs);
|
||||
if (mAllowViewCommandsQueue) {
|
||||
mViewCommandOperations.add(command);
|
||||
} else {
|
||||
mOperations.add(command);
|
||||
}
|
||||
}
|
||||
|
||||
public void enqueueUpdateExtraData(int reactTag, Object extraData) {
|
||||
@@ -742,6 +759,14 @@ public class UIViewOperationQueue {
|
||||
|
||||
// Store the current operation queues to dispatch and create new empty ones to continue
|
||||
// receiving new operations
|
||||
final ArrayList<UIOperation> viewCommandOperations;
|
||||
if (!mViewCommandOperations.isEmpty()) {
|
||||
viewCommandOperations = mViewCommandOperations;
|
||||
mViewCommandOperations = new ArrayList<>();
|
||||
} else {
|
||||
viewCommandOperations = null;
|
||||
}
|
||||
|
||||
final ArrayList<UIOperation> batchedOperations;
|
||||
if (!mOperations.isEmpty()) {
|
||||
batchedOperations = mOperations;
|
||||
@@ -774,6 +799,13 @@ public class UIViewOperationQueue {
|
||||
try {
|
||||
long runStartTime = SystemClock.uptimeMillis();
|
||||
|
||||
// All ViewCommands should be executed first as a perf optimization
|
||||
if (mViewCommandOperations != null) {
|
||||
for (UIOperation viewCommandOp : mViewCommandOperations) {
|
||||
viewCommandOp.execute();
|
||||
}
|
||||
}
|
||||
|
||||
// All nonBatchedOperations should be executed before regular operations as
|
||||
// regular operations may depend on them
|
||||
if (nonBatchedOperations != null) {
|
||||
|
||||
Reference in New Issue
Block a user