mirror of
https://github.com/Instagram/IGListKit
synced 2026-05-23 09:18:29 +00:00
Add experiment for reloadData on large changesets
Summary: Preparing another perf test. I noticed in some surfaces that have **massive** updates (8k+ inserts/deletes) that perf can be pretty awful. This is all due to internals of `UICollectionView` trying to create cells and animate a huge blob of changes. Instead, I'm picking a sensible (is it?) default to just skip batch updates and do `reloadData` instead. Unit tests caught that the `layoutIfNeeded` is required to immediately configure cells. Depends on D5392713 Reviewed By: jeremycohen Differential Revision: D5392882 fbshipit-source-id: e429ddb7bca7400908898ebc6f097a489211b03d
This commit is contained in:
parent
dfc6b687a8
commit
61c1524bb0
2 changed files with 35 additions and 6 deletions
|
|
@ -15,6 +15,7 @@
|
|||
#import <IGListKit/IGListDiff.h>
|
||||
|
||||
#import "UICollectionView+IGListBatchUpdateData.h"
|
||||
#import "IGListIndexSetResultInternal.h"
|
||||
#import "IGListMoveIndexPathInternal.h"
|
||||
#import "IGListReloadIndexPath.h"
|
||||
|
||||
|
|
@ -167,16 +168,21 @@ static NSArray *objectsWithDuplicateIdentifiersRemoved(NSArray<id<IGListDiffable
|
|||
}
|
||||
};
|
||||
|
||||
void (^reloadDataFallback)() = ^{
|
||||
executeUpdateBlocks();
|
||||
[self cleanStateAfterUpdates];
|
||||
[self performBatchUpdatesItemBlockApplied];
|
||||
[collectionView reloadData];
|
||||
[collectionView layoutIfNeeded];
|
||||
executeCompletionBlocks(YES);
|
||||
};
|
||||
|
||||
// if the collection view isn't in a visible window, skip diffing and batch updating. execute all transition blocks,
|
||||
// reload data, execute completion blocks, and get outta here
|
||||
const BOOL iOS83OrLater = (NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_8_3);
|
||||
if (iOS83OrLater && self.allowsBackgroundReloading && collectionView.window == nil) {
|
||||
[self beginPerformBatchUpdatesToObjects:toObjects];
|
||||
executeUpdateBlocks();
|
||||
[self cleanStateAfterUpdates];
|
||||
[self performBatchUpdatesItemBlockApplied];
|
||||
[collectionView reloadData];
|
||||
executeCompletionBlocks(YES);
|
||||
reloadDataFallback();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -217,7 +223,9 @@ static NSArray *objectsWithDuplicateIdentifiersRemoved(NSArray<id<IGListDiffable
|
|||
void (^performUpdate)(IGListIndexSetResult *) = ^(IGListIndexSetResult *result){
|
||||
@try {
|
||||
[delegate listAdapterUpdater:self willPerformBatchUpdatesWithCollectionView:collectionView];
|
||||
if (animated) {
|
||||
if (result.changeCount > 100 && IGListExperimentEnabled(experiments, IGListExperimentReloadDataFallback)) {
|
||||
reloadDataFallback();
|
||||
} else if (animated) {
|
||||
[collectionView performBatchUpdates:^{
|
||||
batchUpdatesBlock(result);
|
||||
} completion:batchUpdatesCompletionBlock];
|
||||
|
|
|
|||
|
|
@ -1521,4 +1521,25 @@
|
|||
[self waitForExpectationsWithTimeout:30 handler:nil];
|
||||
}
|
||||
|
||||
- (void)test_whenMassiveUpdate_thatUpdateApplied {
|
||||
// init empty
|
||||
[self setupWithObjects:@[]];
|
||||
|
||||
((IGListAdapterUpdater *)self.updater).experiments = IGListExperimentReloadDataFallback;
|
||||
|
||||
NSMutableArray *objects = [NSMutableArray new];
|
||||
for (NSInteger i = 0; i < 3000; i++) {
|
||||
[objects addObject:genTestObject(@(i + 1), @4)];
|
||||
}
|
||||
self.dataSource.objects = objects;
|
||||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
[self.adapter performUpdatesAnimated:YES completion:^(BOOL finished) {
|
||||
XCTAssertEqual([self.collectionView numberOfSections], 3000);
|
||||
[expectation fulfill];
|
||||
}];
|
||||
|
||||
[self waitForExpectationsWithTimeout:30 handler:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
Loading…
Reference in a new issue