Permalink
Browse files

Flush UI blocks as soon as they're accumulated

Summary:
public

Currently, we wait to invoke `-flushUIBlocks` until the JavaScript batch to native has completed. This means we may be waiting an unnecessarily long time to perform view hierarchy changes and prop changes.

By instead invoking this after each chunk of enqueued UI blocks, we can perform some updates more eagerly, increasing our utilization of the main thread while splitting up the amount of time we spend running upon it.

This shouldn't affect layout, which is still tied to `-batchDidComplete`, so any visual inconsistencies should be limited to prop changes, which seems acceptable for the dramatic improvement in performance.

Reviewed By: javache

Differential Revision: D2658552

fb-gh-sync-id: 6d4560e21d7da1b02d2f30d1860d60735f11c4b5
  • Loading branch information...
jspahrsummers authored and facebook-github-bot-4 committed Dec 2, 2015
1 parent 802aef9 commit c25c98c00c8c195f85c9fb17eae3cb0c36b465f5
Showing with 38 additions and 0 deletions.
  1. +12 −0 React/Base/RCTBatchedBridge.m
  2. +8 −0 React/Base/RCTBridgeModule.h
  3. +11 −0 React/Modules/RCTUIManager.h
  4. +7 −0 React/Modules/RCTUIManager.m
@@ -720,6 +720,7 @@ - (void)handleBuffer:(id)buffer batchEnded:(BOOL)batchEnded
if (buffer != nil && buffer != (id)kCFNull) {
_wasBatchActive = YES;
[self handleBuffer:buffer];
[self partialBatchDidFlush];
}
if (batchEnded) {
@@ -800,6 +801,17 @@ - (void)handleBuffer:(NSArray<NSArray *> *)buffer
}
}
- (void)partialBatchDidFlush
{
for (RCTModuleData *moduleData in _moduleDataByID) {
if (moduleData.hasInstance && [moduleData.instance respondsToSelector:@selector(partialBatchDidFlush)]) {
[self dispatchBlock:^{
[moduleData.instance partialBatchDidFlush];
} queue:moduleData.methodQueue];
}
}
}
- (void)batchDidComplete
{
// TODO: batchDidComplete is only used by RCTUIManager - can we eliminate this special case?
@@ -235,4 +235,12 @@ RCT_EXTERN void RCTRegisterModule(Class); \
*/
- (void)batchDidComplete;
/**
* Notifies the module that the active batch of JS method invocations has been
* partially flushed.
*
* This occurs before -batchDidComplete, and more frequently.
*/
- (void)partialBatchDidFlush;
@end
@@ -77,6 +77,17 @@ RCT_EXTERN NSString *const RCTUIManagerRootViewKey;
*/
+ (UIView *)JSResponder;
/**
* Normally, UI changes are not applied until the complete batch of method
* invocations from JavaScript to native has completed.
*
* Setting this to YES will flush UI changes sooner, which could potentially
* result in inconsistent UI updates.
*
* The default is NO (recommended).
*/
@property (atomic, assign) BOOL unsafeFlushUIChangesBeforeBatchEnds;
@end
/**
@@ -880,6 +880,13 @@ - (void)_manageChildren:(NSNumber *)containerReactTag
}];
}
- (void)partialBatchDidFlush
{
if (self.unsafeFlushUIChangesBeforeBatchEnds) {
[self flushUIBlocks];
}
}
- (void)batchDidComplete
{
// Gather blocks to be executed now that all view hierarchy manipulations have

0 comments on commit c25c98c

Please sign in to comment.