Skip to content

Commit 447be62

Browse files
p-sunfacebook-github-bot
authored andcommitted
Fix: Install Fabric UIManager before main bundle execution
Summary: Changelog: [Internal] Fix install Fabric UIManager before main bundle execution in Bridgeless In iOS, fixed Bridgeless so that [UIManagerBinding::createAndInstallIfNeeded](https://github.com/facebook/react-native/blob/ce50c43986bae05ad62552be46f4d5bb4a46f097/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp#L24-L41) happens BEFORE the JS main bundle is evaluated. Logic is unchanged in Android. # Before ``` > UI [FBReactModule.mm:325] Initializing FBReactModule: start. > UI [FBReactModule.mm:524] Initializing FBReactModule: end. > UI [FBReactModule.mm:1839] Initializing RCTHost: start. > UI [FBReactModule.mm:1891] Initializing RCTHost: end. > UI[-[FBNavigationControllerObserver navigationController:willShowViewController:animated:]] <FBNewNavigationController: 0x7fd0e7859400> will show <FBReactRootViewController: 0x7fd0e7161a00; react_GemstoneHomeRoute> (animated: 1) > VJCPP ****** ReactInstance loadScript -> evaluateJavaScript start <--- loads Main Bundle > UI[-[FBNavigationControllerObserver navigationController:didShowViewController:animated:]] <FBNewNavigationController: 0x7fd0e7859400> did show <FBReactRootViewController: 0x7fd0e7161a00; react_GemstoneHomeRoute> (animated: 1) > VJCPP ****** ReactInstance loadScript -> evaluateJavaScript end > VJCPP ****** UIManagerBinding createAndInstallIfNeeded <--- should happen BEFORE evaluateJavaScript ``` Reviewed By: RSNara Differential Revision: D39493654 fbshipit-source-id: 4491d6de110966b2eb4f554ff4db8548899020e3
1 parent e2028a8 commit 447be62

File tree

6 files changed

+22
-3
lines changed

6 files changed

+22
-3
lines changed

React/Fabric/RCTSurfacePresenter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ NS_ASSUME_NONNULL_BEGIN
2828
@interface RCTSurfacePresenter : NSObject
2929

3030
- (instancetype)initWithContextContainer:(facebook::react::ContextContainer::Shared)contextContainer
31-
runtimeExecutor:(facebook::react::RuntimeExecutor)runtimeExecutor;
31+
runtimeExecutor:(facebook::react::RuntimeExecutor)runtimeExecutor
32+
bindingsInstallExecutor:(facebook::react::RuntimeExecutor)bindingsInstallExecutor;
3233

3334
@property (nonatomic) facebook::react::ContextContainer::Shared contextContainer;
3435
@property (nonatomic) facebook::react::RuntimeExecutor runtimeExecutor;

React/Fabric/RCTSurfacePresenter.mm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,20 @@ @implementation RCTSurfacePresenter {
7979
RCTScheduler *_Nullable _scheduler; // Thread-safe. Pointer is protected by `_schedulerAccessMutex`.
8080
ContextContainer::Shared _contextContainer; // Protected by `_schedulerLifeCycleMutex`.
8181
RuntimeExecutor _runtimeExecutor; // Protected by `_schedulerLifeCycleMutex`.
82+
RuntimeExecutor _bindingsInstallExecutor; // Only used for installing bindings.
8283

8384
butter::shared_mutex _observerListMutex;
8485
std::vector<__weak id<RCTSurfacePresenterObserver>> _observers; // Protected by `_observerListMutex`.
8586
}
8687

8788
- (instancetype)initWithContextContainer:(ContextContainer::Shared)contextContainer
8889
runtimeExecutor:(RuntimeExecutor)runtimeExecutor
90+
bindingsInstallExecutor:(RuntimeExecutor)bindingsInstallExecutor
8991
{
9092
if (self = [super init]) {
9193
assert(contextContainer && "RuntimeExecutor must be not null.");
9294
_runtimeExecutor = runtimeExecutor;
95+
_bindingsInstallExecutor = bindingsInstallExecutor;
9396
_contextContainer = contextContainer;
9497

9598
_surfaceRegistry = [RCTSurfaceRegistry new];
@@ -295,6 +298,7 @@ - (RCTScheduler *)_createScheduler
295298
}
296299

297300
toolbox.runtimeExecutor = runtimeExecutor;
301+
toolbox.bindingsInstallExecutor = _bindingsInstallExecutor;
298302

299303
toolbox.mainRunLoopObserverFactory = [](RunLoopObserver::Activity activities,
300304
RunLoopObserver::WeakOwner const &owner) {

React/Fabric/RCTSurfacePresenterBridgeAdapter.mm

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,10 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge contextContainer:(ContextCont
8989
{
9090
if (self = [super init]) {
9191
contextContainer->update(*RCTContextContainerFromBridge(bridge));
92+
auto runtimeExecuter = RCTRuntimeExecutorFromBridge(bridge);
9293
_surfacePresenter = [[RCTSurfacePresenter alloc] initWithContextContainer:contextContainer
93-
runtimeExecutor:RCTRuntimeExecutorFromBridge(bridge)];
94+
runtimeExecutor:runtimeExecuter
95+
bindingsInstallExecutor:runtimeExecuter];
9496

9597
_bridge = bridge;
9698
_batchedBridge = [_bridge batchedBridge] ?: _bridge;

ReactAndroid/src/main/jni/react/fabric/Binding.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,12 @@ void Binding::installFabricUIManager(
462462
auto toolbox = SchedulerToolbox{};
463463
toolbox.contextContainer = contextContainer;
464464
toolbox.componentRegistryFactory = componentsRegistry->buildRegistryFunction;
465+
466+
// TODO: (T130208323) runtimeExecutor should execute lambdas after
467+
// main bundle eval, and bindingsInstallExecutor should execute before.
468+
toolbox.bindingsInstallExecutor = runtimeExecutor;
465469
toolbox.runtimeExecutor = runtimeExecutor;
470+
466471
toolbox.synchronousEventBeatFactory = synchronousBeatFactory;
467472
toolbox.asynchronousEventBeatFactory = asynchronousBeatFactory;
468473

ReactCommon/react/renderer/scheduler/Scheduler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ Scheduler::Scheduler(
9595
uiManager->setDelegate(this);
9696
uiManager->setComponentDescriptorRegistry(componentDescriptorRegistry_);
9797

98-
runtimeExecutor_([uiManager](jsi::Runtime &runtime) {
98+
schedulerToolbox.bindingsInstallExecutor([uiManager](jsi::Runtime &runtime) {
9999
UIManagerBinding::createAndInstallIfNeeded(runtime, uiManager);
100100
});
101101

ReactCommon/react/renderer/scheduler/SchedulerToolbox.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ struct SchedulerToolbox final {
4040

4141
/*
4242
* Represents running JavaScript VM and associated execution queue.
43+
* Can execute lambdas before main bundle has loaded.
44+
*/
45+
RuntimeExecutor bindingsInstallExecutor;
46+
47+
/*
48+
* Represents running JavaScript VM and associated execution queue.
49+
* Only executes lambdas after main bundle has loaded.
4350
*/
4451
RuntimeExecutor runtimeExecutor;
4552

0 commit comments

Comments
 (0)