Skip to content

Commit

Permalink
Fabric: Simplifying RCTPerformMountInstructions
Browse files Browse the repository at this point in the history
Summary:
This diff inlines all mount-instruction functions into a single one - RCTPerformMountInstructions.
The main purpose is to reduce the number of calls to `RCTComponentViewRegistry` for some instructions. E.g., before the change, the `Insert` (or `Update`) instruction had seven identical calls to the registry. That's not a huge deal but there is no need to pay for it either. Maybe it can save us a couple of milliseconds during TTI.

The code of those functions is quite straight-forward, so this change probably even improves readability.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D22402987

fbshipit-source-id: 043a4114ba42622e9ed226f4d5e41ed45c1b066c
  • Loading branch information
shergin authored and facebook-github-bot committed Jul 7, 2020
1 parent e23e932 commit f2fdc1a
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 130 deletions.
5 changes: 3 additions & 2 deletions React/Fabric/Mounting/RCTComponentViewRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ NS_ASSUME_NONNULL_BEGIN
* for given `componentHandle` and with given `tag`.
* #RefuseSingleUse
*/
- (RCTComponentViewDescriptor)dequeueComponentViewWithComponentHandle:(facebook::react::ComponentHandle)componentHandle
tag:(facebook::react::Tag)tag;
- (RCTComponentViewDescriptor const &)dequeueComponentViewWithComponentHandle:
(facebook::react::ComponentHandle)componentHandle
tag:(facebook::react::Tag)tag;

/**
* Puts a given native component view to the recycle pool.
Expand Down
9 changes: 4 additions & 5 deletions React/Fabric/Mounting/RCTComponentViewRegistry.mm
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ - (void)preallocateViewComponents
}
}

- (RCTComponentViewDescriptor)dequeueComponentViewWithComponentHandle:(ComponentHandle)componentHandle tag:(Tag)tag
- (RCTComponentViewDescriptor const &)dequeueComponentViewWithComponentHandle:(ComponentHandle)componentHandle
tag:(Tag)tag
{
RCTAssertMainQueue();

Expand All @@ -76,10 +77,8 @@ - (RCTComponentViewDescriptor)dequeueComponentViewWithComponentHandle:(Component

auto componentViewDescriptor = [self _dequeueComponentViewWithComponentHandle:componentHandle];
componentViewDescriptor.view.tag = tag;

_registry.insert({tag, componentViewDescriptor});

return componentViewDescriptor;
auto it = _registry.insert({tag, componentViewDescriptor});
return it.first->second;
}

- (void)enqueueComponentViewWithComponentHandle:(ComponentHandle)componentHandle
Expand Down
177 changes: 54 additions & 123 deletions React/Fabric/Mounting/RCTMountingManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -21,170 +21,101 @@
#import "RCTConversions.h"
#import "RCTMountingTransactionObserverCoordinator.h"

using namespace facebook;
using namespace facebook::react;

// `Create` instruction
static void RNCreateMountInstruction(
ShadowViewMutation const &mutation,
RCTComponentViewRegistry *registry,
RCTMountingTransactionObserverCoordinator &observerCoordinator,
SurfaceId surfaceId)
{
auto componentViewDescriptor =
[registry dequeueComponentViewWithComponentHandle:mutation.newChildShadowView.componentHandle
tag:mutation.newChildShadowView.tag];

observerCoordinator.registerViewComponentDescriptor(componentViewDescriptor, surfaceId);
}

// `Delete` instruction
static void RNDeleteMountInstruction(
ShadowViewMutation const &mutation,
RCTComponentViewRegistry *registry,
RCTMountingTransactionObserverCoordinator &observerCoordinator,
SurfaceId surfaceId)
{
auto const &oldChildShadowView = mutation.oldChildShadowView;
auto const &componentViewDescriptor = [registry componentViewDescriptorWithTag:oldChildShadowView.tag];
observerCoordinator.unregisterViewComponentDescriptor(componentViewDescriptor, surfaceId);
[registry enqueueComponentViewWithComponentHandle:oldChildShadowView.componentHandle
tag:oldChildShadowView.tag
componentViewDescriptor:componentViewDescriptor];
}

// `Insert` instruction
static void RNInsertMountInstruction(ShadowViewMutation const &mutation, RCTComponentViewRegistry *registry)
{
auto const &newShadowView = mutation.newChildShadowView;
auto const &parentShadowView = mutation.parentShadowView;

auto const &childComponentViewDescriptor = [registry componentViewDescriptorWithTag:newShadowView.tag];
auto const &parentComponentViewDescriptor = [registry componentViewDescriptorWithTag:parentShadowView.tag];

[parentComponentViewDescriptor.view mountChildComponentView:childComponentViewDescriptor.view index:mutation.index];
}

// `Remove` instruction
static void RNRemoveMountInstruction(ShadowViewMutation const &mutation, RCTComponentViewRegistry *registry)
{
auto const &oldShadowView = mutation.oldChildShadowView;
auto const &parentShadowView = mutation.parentShadowView;

auto const &childComponentViewDescriptor = [registry componentViewDescriptorWithTag:oldShadowView.tag];
auto const &parentComponentViewDescriptor = [registry componentViewDescriptorWithTag:parentShadowView.tag];

[parentComponentViewDescriptor.view unmountChildComponentView:childComponentViewDescriptor.view index:mutation.index];
}

// `Update Props` instruction
static void RNUpdatePropsMountInstruction(ShadowViewMutation const &mutation, RCTComponentViewRegistry *registry)
{
auto const &oldShadowView = mutation.oldChildShadowView;
auto const &newShadowView = mutation.newChildShadowView;
auto const &componentViewDescriptor = [registry componentViewDescriptorWithTag:newShadowView.tag];
[componentViewDescriptor.view updateProps:newShadowView.props oldProps:oldShadowView.props];
}

// `Update EventEmitter` instruction
static void RNUpdateEventEmitterMountInstruction(ShadowViewMutation const &mutation, RCTComponentViewRegistry *registry)
{
auto const &newShadowView = mutation.newChildShadowView;
auto const &componentViewDescriptor = [registry componentViewDescriptorWithTag:newShadowView.tag];
[componentViewDescriptor.view updateEventEmitter:newShadowView.eventEmitter];
}

// `Update LayoutMetrics` instruction
static void RNUpdateLayoutMetricsMountInstruction(
ShadowViewMutation const &mutation,
RCTComponentViewRegistry *registry)
{
auto const &oldShadowView = mutation.oldChildShadowView;
auto const &newShadowView = mutation.newChildShadowView;
auto const &componentViewDescriptor = [registry componentViewDescriptorWithTag:newShadowView.tag];
[componentViewDescriptor.view updateLayoutMetrics:newShadowView.layoutMetrics
oldLayoutMetrics:oldShadowView.layoutMetrics];
}

// `Update State` instruction
static void RNUpdateStateMountInstruction(ShadowViewMutation const &mutation, RCTComponentViewRegistry *registry)
{
auto const &oldShadowView = mutation.oldChildShadowView;
auto const &newShadowView = mutation.newChildShadowView;
auto const &componentViewDescriptor = [registry componentViewDescriptorWithTag:newShadowView.tag];
[componentViewDescriptor.view updateState:newShadowView.state oldState:oldShadowView.state];
}

// `Finalize Updates` instruction
static void RNFinalizeUpdatesMountInstruction(
ShadowViewMutation const &mutation,
RNComponentViewUpdateMask mask,
RCTComponentViewRegistry *registry)
{
auto const &newShadowView = mutation.newChildShadowView;
auto const &componentViewDescriptor = [registry componentViewDescriptorWithTag:newShadowView.tag];
[componentViewDescriptor.view finalizeUpdates:mask];
}

// `Update` instruction
static void RNPerformMountInstructions(
static void RCTPerformMountInstructions(
ShadowViewMutationList const &mutations,
RCTComponentViewRegistry *registry,
RCTMountingTransactionObserverCoordinator &observerCoordinator,
SurfaceId surfaceId)
{
SystraceSection s("RNPerformMountInstructions");
SystraceSection s("RCTPerformMountInstructions");

[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
for (auto const &mutation : mutations) {
switch (mutation.type) {
case ShadowViewMutation::Create: {
RNCreateMountInstruction(mutation, registry, observerCoordinator, surfaceId);
auto &newChildShadowView = mutation.newChildShadowView;
auto &newChildViewDescriptor =
[registry dequeueComponentViewWithComponentHandle:newChildShadowView.componentHandle
tag:newChildShadowView.tag];
observerCoordinator.registerViewComponentDescriptor(newChildViewDescriptor, surfaceId);
break;
}

case ShadowViewMutation::Delete: {
RNDeleteMountInstruction(mutation, registry, observerCoordinator, surfaceId);
auto &oldChildShadowView = mutation.oldChildShadowView;
auto &oldChildViewDescriptor = [registry componentViewDescriptorWithTag:oldChildShadowView.tag];

observerCoordinator.unregisterViewComponentDescriptor(oldChildViewDescriptor, surfaceId);

[registry enqueueComponentViewWithComponentHandle:oldChildShadowView.componentHandle
tag:oldChildShadowView.tag
componentViewDescriptor:oldChildViewDescriptor];
break;
}

case ShadowViewMutation::Insert: {
RNUpdatePropsMountInstruction(mutation, registry);
RNUpdateEventEmitterMountInstruction(mutation, registry);
RNUpdateStateMountInstruction(mutation, registry);
RNUpdateLayoutMetricsMountInstruction(mutation, registry);
RNFinalizeUpdatesMountInstruction(mutation, RNComponentViewUpdateMaskAll, registry);
RNInsertMountInstruction(mutation, registry);
auto &oldChildShadowView = mutation.oldChildShadowView;
auto &newChildShadowView = mutation.newChildShadowView;
auto &parentShadowView = mutation.parentShadowView;
auto &newChildViewDescriptor = [registry componentViewDescriptorWithTag:newChildShadowView.tag];
auto &parentViewDescriptor = [registry componentViewDescriptorWithTag:parentShadowView.tag];

UIView<RCTComponentViewProtocol> *newChildComponentView = newChildViewDescriptor.view;

[newChildComponentView updateProps:newChildShadowView.props oldProps:oldChildShadowView.props];
[newChildComponentView updateEventEmitter:newChildShadowView.eventEmitter];
[newChildComponentView updateState:newChildShadowView.state oldState:oldChildShadowView.state];
[newChildComponentView updateLayoutMetrics:newChildShadowView.layoutMetrics
oldLayoutMetrics:oldChildShadowView.layoutMetrics];
[newChildComponentView finalizeUpdates:RNComponentViewUpdateMaskAll];

[parentViewDescriptor.view mountChildComponentView:newChildComponentView index:mutation.index];
break;
}

case ShadowViewMutation::Remove: {
RNRemoveMountInstruction(mutation, registry);
auto &oldChildShadowView = mutation.oldChildShadowView;
auto &parentShadowView = mutation.parentShadowView;
auto &oldChildViewDescriptor = [registry componentViewDescriptorWithTag:oldChildShadowView.tag];
auto &parentViewDescriptor = [registry componentViewDescriptorWithTag:parentShadowView.tag];
[parentViewDescriptor.view unmountChildComponentView:oldChildViewDescriptor.view index:mutation.index];
break;
}

case ShadowViewMutation::Update: {
auto const &oldChildShadowView = mutation.oldChildShadowView;
auto const &newChildShadowView = mutation.newChildShadowView;
auto &oldChildShadowView = mutation.oldChildShadowView;
auto &newChildShadowView = mutation.newChildShadowView;
auto &newChildViewDescriptor = [registry componentViewDescriptorWithTag:newChildShadowView.tag];
UIView<RCTComponentViewProtocol> *newChildComponentView = newChildViewDescriptor.view;

auto mask = RNComponentViewUpdateMask{};

if (oldChildShadowView.props != newChildShadowView.props) {
RNUpdatePropsMountInstruction(mutation, registry);
[newChildComponentView updateProps:newChildShadowView.props oldProps:oldChildShadowView.props];
mask |= RNComponentViewUpdateMaskProps;
}

if (oldChildShadowView.eventEmitter != newChildShadowView.eventEmitter) {
RNUpdateEventEmitterMountInstruction(mutation, registry);
[newChildComponentView updateEventEmitter:newChildShadowView.eventEmitter];
mask |= RNComponentViewUpdateMaskEventEmitter;
}

if (oldChildShadowView.state != newChildShadowView.state) {
RNUpdateStateMountInstruction(mutation, registry);
[newChildComponentView updateState:newChildShadowView.state oldState:oldChildShadowView.state];
mask |= RNComponentViewUpdateMaskState;
}

if (oldChildShadowView.layoutMetrics != newChildShadowView.layoutMetrics) {
RNUpdateLayoutMetricsMountInstruction(mutation, registry);
[newChildComponentView updateLayoutMetrics:newChildShadowView.layoutMetrics
oldLayoutMetrics:oldChildShadowView.layoutMetrics];
mask |= RNComponentViewUpdateMaskLayoutMetrics;
}

if (mask != RNComponentViewUpdateMaskNone) {
RNFinalizeUpdatesMountInstruction(mutation, mask, registry);
[newChildComponentView finalizeUpdates:mask];
}

break;
Expand Down Expand Up @@ -284,7 +215,7 @@ - (void)performTransaction:(MountingCoordinator::Shared const &)mountingCoordina
[self.delegate mountingManager:self willMountComponentsWithRootTag:surfaceId];
_observerCoordinator.notifyObserversMountingTransactionWillMount({surfaceId, number, telemetry});
telemetry.willMount();
RNPerformMountInstructions(mutations, self.componentViewRegistry, _observerCoordinator, surfaceId);
RCTPerformMountInstructions(mutations, self.componentViewRegistry, _observerCoordinator, surfaceId);
telemetry.didMount();
_observerCoordinator.notifyObserversMountingTransactionDidMount({surfaceId, number, telemetry});
[self.delegate mountingManager:self didMountComponentsWithRootTag:surfaceId];
Expand Down

0 comments on commit f2fdc1a

Please sign in to comment.