Scrollview updatedChildFrames data controlled by prop

Summary: Optimize ScrollView by adding flag "DEPRECATED_sendUpdatedChildFrames" to gate whether updatedChildFrames data is computed and propagated on scroll events.  The frame data is used in ListView by the onChangeVisibleRows prop.  When this prop is not defined, unnecessary computation in ScrollView should not be performed.

Reviewed By: sahrens

Differential Revision: D5174898

fbshipit-source-id: e3eaed8760b76becf14dfeb00122bdebdaeae4ef
This commit is contained in:
John O'Leary 2017-06-08 11:49:39 -07:00 коммит произвёл Facebook Github Bot
Родитель d062cc252e
Коммит 62b20ce582
5 изменённых файлов: 24 добавлений и 8 удалений

Просмотреть файл

@ -388,6 +388,15 @@ const ScrollView = React.createClass({
'always',
'never',
]),
/**
* When true, ScrollView will emit updateChildFrames data in scroll events,
* otherwise will not compute or emit child frame data. This only exists
* to support legacy issues, `onLayout` should be used instead to retrieve
* frame data.
* The default value is false.
* @platform ios
*/
DEPRECATED_sendUpdatedChildFrames: PropTypes.bool,
},
mixins: [ScrollResponder.Mixin],
@ -682,6 +691,9 @@ const ScrollView = React.createClass({
this.props.alwaysBounceVertical :
!this.props.horizontal;
const DEPRECATED_sendUpdatedChildFrames =
!!this.props.DEPRECATED_sendUpdatedChildFrames;
const baseStyle = this.props.horizontal ? styles.baseHorizontal : styles.baseVertical;
const props = {
...this.props,
@ -710,6 +722,7 @@ const ScrollView = React.createClass({
scrollEventThrottle: hasStickyHeaders ? 1 : this.props.scrollEventThrottle,
sendMomentumEvents: (this.props.onMomentumScrollBegin || this.props.onMomentumScrollEnd) ?
true : false,
DEPRECATED_sendUpdatedChildFrames,
};
const { decelerationRate } = this.props;

Просмотреть файл

@ -508,6 +508,7 @@ var ListView = React.createClass({
ref: this._setScrollComponentRef,
onContentSizeChange: this._onContentSizeChange,
onLayout: this._onLayout,
DEPRECATED_sendUpdatedChildFrames: props.onChangeVisibleRows !== undefined,
}, header, bodyComponents, footer);
},

Просмотреть файл

@ -42,6 +42,7 @@
@property (nonatomic, assign) UIEdgeInsets contentInset;
@property (nonatomic, assign) BOOL automaticallyAdjustContentInsets;
@property (nonatomic, assign) BOOL DEPRECATED_sendUpdatedChildFrames;
@property (nonatomic, assign) NSTimeInterval scrollEventThrottle;
@property (nonatomic, assign) BOOL centerContent;
@property (nonatomic, assign) int snapToInterval;

Просмотреть файл

@ -109,7 +109,6 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
- (RCTScrollEvent *)coalesceWithEvent:(RCTScrollEvent *)newEvent
{
NSArray<NSDictionary *> *updatedChildFrames = [_userData[@"updatedChildFrames"] arrayByAddingObjectsFromArray:newEvent->_userData[@"updatedChildFrames"]];
if (updatedChildFrames) {
NSMutableDictionary *userData = [newEvent->_userData mutableCopy];
userData[@"updatedChildFrames"] = updatedChildFrames;
@ -338,6 +337,7 @@ static inline BOOL isRectInvalid(CGRect rect) {
_scrollView.delegate = self;
_scrollView.delaysContentTouches = NO;
_automaticallyAdjustContentInsets = YES;
_DEPRECATED_sendUpdatedChildFrames = NO;
_contentInset = UIEdgeInsetsZero;
_contentSize = CGSizeZero;
_lastClippedToRect = CGRectNull;
@ -587,9 +587,7 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, onScroll)
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self updateClippedSubviews];
NSTimeInterval now = CACurrentMediaTime();
/**
* TODO: this logic looks wrong, and it may be because it is. Currently, if _scrollEventThrottle
* is set to zero (the default), the "didScroll" event is only sent once per scroll, instead of repeatedly
@ -599,16 +597,18 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, onScroll)
if (_allowNextScrollNoMatterWhat ||
(_scrollEventThrottle > 0 && _scrollEventThrottle < (now - _lastScrollDispatchTime))) {
// Calculate changed frames
NSArray<NSDictionary *> *childFrames = [self calculateChildFramesData];
// Dispatch event
RCT_SEND_SCROLL_EVENT(onScroll, (@{@"updatedChildFrames": childFrames}));
if (_DEPRECATED_sendUpdatedChildFrames) {
// Calculate changed frames
RCT_SEND_SCROLL_EVENT(onScroll, (@{@"updatedChildFrames": [self calculateChildFramesData]}));
} else {
RCT_SEND_SCROLL_EVENT(onScroll, nil);
}
// Update dispatch time
_lastScrollDispatchTime = now;
_allowNextScrollNoMatterWhat = NO;
}
RCT_FORWARD_SCROLL_EVENT(scrollViewDidScroll:scrollView);
}

Просмотреть файл

@ -80,6 +80,7 @@ RCT_EXPORT_VIEW_PROPERTY(onScrollEndDrag, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onMomentumScrollBegin, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onMomentumScrollEnd, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onScrollAnimationEnd, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(DEPRECATED_sendUpdatedChildFrames, BOOL)
// overflow is used both in css-layout as well as by react-native. In css-layout
// we always want to treat overflow as scroll but depending on what the overflow