mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Implement limit to execute pre-mount operations
Summary: This diff implements a limit on the execution of pre-allocation of views, taking into consideration the time it is left on the frame, with a maximum of 8 ms / frame Reviewed By: shergin Differential Revision: D14252172 fbshipit-source-id: 1780a489122a8bc476d6ec7c92b45fdc58993e1d
This commit is contained in:
committed by
Facebook Github Bot
parent
aa69e51096
commit
ed8573f957
@@ -18,6 +18,7 @@ import android.os.SystemClock;
|
||||
import android.support.annotation.GuardedBy;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.infer.annotation.Assertions;
|
||||
@@ -57,6 +58,7 @@ import com.facebook.react.uimanager.ViewManagerPropertyUpdater;
|
||||
import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||
import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
import com.facebook.systrace.Systrace;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -69,6 +71,8 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
private static final String TAG = FabricUIManager.class.getSimpleName();
|
||||
|
||||
private static final Map<String, String> sComponentNames = new HashMap<>();
|
||||
private static final int FRAME_TIME_MS = 16;
|
||||
private static final int MAX_TIME_IN_FRAME_FOR_NON_BATCHED_OPERATIONS_MS = 8;
|
||||
|
||||
static {
|
||||
FabricSoLoader.staticInit();
|
||||
@@ -101,7 +105,7 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
private List<MountItem> mMountItems = new ArrayList<>();
|
||||
|
||||
@GuardedBy("mPreMountItemsLock")
|
||||
private List<MountItem> mPreMountItems = new ArrayList<>();
|
||||
private ArrayDeque<MountItem> mPreMountItems = new ArrayDeque<>();
|
||||
|
||||
@ThreadConfined(UI)
|
||||
private final DispatchUIFrameCallback mDispatchUIFrameCallback;
|
||||
@@ -302,58 +306,56 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
}
|
||||
|
||||
if (UiThreadUtil.isOnUiThread()) {
|
||||
flushMountItems();
|
||||
dispatchMountItems();
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void flushMountItems() {
|
||||
if (!mIsMountingEnabled) {
|
||||
FLog.w(
|
||||
ReactConstants.TAG,
|
||||
"Not flushing pending UI operations because of previously thrown Exception");
|
||||
return;
|
||||
private void dispatchMountItems() {
|
||||
mRunStartTime = SystemClock.uptimeMillis();
|
||||
List<MountItem> mountItemsToDispatch;
|
||||
synchronized (mMountItemsLock) {
|
||||
mountItemsToDispatch = mMountItems;
|
||||
mMountItems = new ArrayList<>();
|
||||
}
|
||||
|
||||
try {
|
||||
List<MountItem> preMountItemsToDispatch;
|
||||
synchronized (mPreMountItemsLock) {
|
||||
preMountItemsToDispatch = mPreMountItems;
|
||||
mPreMountItems = new ArrayList<>();
|
||||
}
|
||||
|
||||
mRunStartTime = SystemClock.uptimeMillis();
|
||||
List<MountItem> mountItemsToDispatch;
|
||||
synchronized (mMountItemsLock) {
|
||||
mountItemsToDispatch = mMountItems;
|
||||
mMountItems = new ArrayList<>();
|
||||
}
|
||||
|
||||
long nonBatchedExecutionStartTime = SystemClock.uptimeMillis();
|
||||
Systrace.beginSection(
|
||||
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);
|
||||
"FabricUIManager::mountViews (" + mountItemsToDispatch.size() + " batches)");
|
||||
|
||||
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);
|
||||
mIsMountingEnabled = false;
|
||||
throw ex;
|
||||
long batchedExecutionStartTime = SystemClock.uptimeMillis();
|
||||
for (MountItem mountItem : mountItemsToDispatch) {
|
||||
mountItem.execute(mMountingManager);
|
||||
}
|
||||
mBatchedExecutionTime = SystemClock.uptimeMillis() - batchedExecutionStartTime;
|
||||
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void dispatchPreMountItems(long frameTimeNanos) {
|
||||
long nonBatchedExecutionStartTime = SystemClock.uptimeMillis();
|
||||
Systrace.beginSection(
|
||||
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
|
||||
"FabricUIManager::premountViews");
|
||||
|
||||
while (true) {
|
||||
long timeLeftInFrame = FRAME_TIME_MS - ((System.nanoTime() - frameTimeNanos) / 1000000);
|
||||
if (timeLeftInFrame < MAX_TIME_IN_FRAME_FOR_NON_BATCHED_OPERATIONS_MS) {
|
||||
break;
|
||||
}
|
||||
|
||||
MountItem preMountItemsToDispatch;
|
||||
synchronized (mPreMountItemsLock) {
|
||||
if (mPreMountItems.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
preMountItemsToDispatch = mPreMountItems.pollFirst();
|
||||
}
|
||||
|
||||
preMountItemsToDispatch.execute(mMountingManager);
|
||||
}
|
||||
mNonBatchedExecutionTime = SystemClock.uptimeMillis() - nonBatchedExecutionStartTime;
|
||||
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
|
||||
}
|
||||
|
||||
public void setBinding(Binding binding) {
|
||||
@@ -454,7 +456,11 @@ public class FabricUIManager implements UIManager, LifecycleEventListener {
|
||||
}
|
||||
|
||||
try {
|
||||
flushMountItems();
|
||||
|
||||
dispatchPreMountItems(frameTimeNanos);
|
||||
|
||||
dispatchMountItems();
|
||||
|
||||
} catch (Exception ex) {
|
||||
FLog.i(ReactConstants.TAG, "Exception thrown when executing UIFrameGuarded", ex);
|
||||
mIsMountingEnabled = false;
|
||||
|
||||
Reference in New Issue
Block a user