diff --git a/React/Base/macOS/RCTUIKit.m b/React/Base/macOS/RCTUIKit.m index 395944a14df823..db0cc39f6f3b26 100644 --- a/React/Base/macOS/RCTUIKit.m +++ b/React/Base/macOS/RCTUIKit.m @@ -13,6 +13,8 @@ #import +#define RCT_LAYOUT_THROTTLE 0.25 + static char RCTGraphicsContextSizeKey; // @@ -209,6 +211,9 @@ @implementation RCTUIView // TODO(macOS ISS#3536887) BOOL _clipsToBounds; BOOL _opaque; BOOL _userInteractionEnabled; + + NSDate *_lastLayout; + BOOL _throttleLayout; } + (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key @@ -236,7 +241,7 @@ @implementation RCTUIView // TODO(macOS ISS#3536887) if (self != nil) { self.wantsLayer = YES; self->_userInteractionEnabled = YES; - + self->_lastLayout = [NSDate new]; } return self; } @@ -329,8 +334,22 @@ - (void)drawRect:(CGRect)rect - (void)layout { - if (self.window != nil) { - [self layoutSubviews]; + if (self.window != nil && !_throttleLayout) { + NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:_lastLayout]; + if (interval >= RCT_LAYOUT_THROTTLE) { + _lastLayout = [NSDate new]; + [self layoutSubviews]; + } else { + _throttleLayout = YES; + __weak typeof(self) weakSelf = self; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, RCT_LAYOUT_THROTTLE * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ + typeof(self) strongSelf = weakSelf; + if (strongSelf != nil) { + strongSelf->_throttleLayout = NO; + [strongSelf setNeedsLayout]; + } + }); + } } }