From 233998db1e11853b8e54800a7a4b133912f4b2e1 Mon Sep 17 00:00:00 2001 From: wwwcg Date: Thu, 26 Oct 2023 22:59:47 +0800 Subject: [PATCH 1/3] fix(ios): listview performance optimization and bug fix p1 --- framework/examples/ios-demo/podfile | 4 +-- .../NativeRenderBaseListViewDataSource.mm | 11 +++++++- .../NativeRenderObjectWaterfall.h | 7 +++++ .../NativeRenderObjectWaterfall.mm | 27 ++++++++++++++----- .../NativeRenderWaterfallView.mm | 2 +- 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/framework/examples/ios-demo/podfile b/framework/examples/ios-demo/podfile index 1b27e1b7249..05ad4466a19 100644 --- a/framework/examples/ios-demo/podfile +++ b/framework/examples/ios-demo/podfile @@ -5,8 +5,8 @@ install! 'cocoapods', :deterministic_uuids => false, :generate_multiple_pod_projects => true -#use_frameworks! :linkage => :static # 静态库framework格式 -#ENV["use_frameworks"] = "true" # for hippy when set use_frameworks! +use_frameworks! :linkage => :static # 静态库framework格式 +ENV["use_frameworks"] = "true" # for hippy when set use_frameworks! workspace 'HippyDemo.xcworkspace' diff --git a/renderer/native/ios/renderer/component/listview/NativeRenderBaseListViewDataSource.mm b/renderer/native/ios/renderer/component/listview/NativeRenderBaseListViewDataSource.mm index fc2d095ae47..032d9f7fb59 100644 --- a/renderer/native/ios/renderer/component/listview/NativeRenderBaseListViewDataSource.mm +++ b/renderer/native/ios/renderer/component/listview/NativeRenderBaseListViewDataSource.mm @@ -166,7 +166,16 @@ - (void)applyDiff:(NativeRenderBaseListViewDataSource *)another completion(YES); return; } -// NSArray *batchUpdateInvocations = [self cellViewChangeInvocation:another context:context forCollectionView:view]; + + // Attention, we do partial reload only when 1 item change! + // because differential refreshing causes the display event of the cell to not trigger, + // So we limit this to when only one cell is updated + if (context.allChangedItems.count > 1) { + [view reloadData]; + completion(YES); + } + + // The following logic is not perfect and needs to be further refined NSMutableArray *batchUpdate = [NSMutableArray arrayWithCapacity:8]; [self cellDiffFromAnother:another sectionStartAt:0 diff --git a/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.h b/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.h index a37c728a081..08b1eb9014c 100644 --- a/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.h +++ b/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.h @@ -32,8 +32,15 @@ NS_ASSUME_NONNULL_BEGIN - (NSSet<__kindof HippyShadowView *> *)deletedItems; - (NSHashTable<__kindof HippyShadowView *> *)movedItems; +/// Clear all items recorded. - (void)clear; +/// Whether has changed item. +- (BOOL)hasChanges; + +/// Get all chaned items. +- (NSSet *)allChangedItems; + @end @interface NativeRenderObjectWaterfall : HippyShadowView diff --git a/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.mm b/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.mm index 9008fe669d1..2b4ad5a2a2a 100644 --- a/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.mm +++ b/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.mm @@ -73,9 +73,8 @@ - (void)appendMovedItem:(__kindof HippyShadowView *)objectView { } - (void)appendFrameChangedItem:(__kindof HippyShadowView *)objectView { - if (![_addedItems containsObject:objectView]) { - [_frameChangedItems addObject:objectView]; - } + // _frameChangedItems may be also in other addedItems/movedItems + [_frameChangedItems addObject:objectView]; } - (NSSet<__kindof HippyShadowView *> *)deletedItems { @@ -94,6 +93,19 @@ - (void)appendFrameChangedItem:(__kindof HippyShadowView *)objectView { return [_frameChangedItems copy]; } +- (BOOL)hasChanges { + return _addedItems.count != 0 || _deletedItems.count != 0 || _movedItems.count != 0 || _frameChangedItems.count != 0; +} + +- (NSSet *)allChangedItems { + NSMutableSet *allChanges = [NSMutableSet set]; + [allChanges addObjectsFromArray:_addedItems.allObjects]; + [allChanges addObjectsFromArray:_deletedItems.allObjects]; + [allChanges addObjectsFromArray:_movedItems.allObjects]; + [allChanges addObjectsFromArray:_frameChangedItems.allObjects]; + return allChanges; +} + - (void)clear { [_deletedItems removeAllObjects]; [_addedItems removeAllObjects]; @@ -163,11 +175,14 @@ - (void)itemFrameChanged:(__kindof NativeRenderObjectWaterfallItem *)item { - (void)amendLayoutBeforeMount:(NSMutableSet *)blocks { if ([self isPropagationDirty:NativeRenderUpdateLifecycleLayoutDirtied]) { - __weak NativeRenderObjectWaterfall *weakSelf = self; + if (!_itemChangeContext.hasChanges) { + return; + } WaterfallItemChangeContext *context = [_itemChangeContext copy]; NSArray *dataSource = [self.subcomponents copy]; + __weak __typeof(self)weakSelf = self; NativeRenderApplierBlock block = ^void(NSDictionary *viewRegistry) { - NativeRenderObjectWaterfall *strongSelf = weakSelf; + __strong __typeof(weakSelf)strongSelf = weakSelf; if (!strongSelf) { return; } @@ -175,7 +190,7 @@ - (void)amendLayoutBeforeMount:(NSMutableSet *)blocks HippyAssert([view isKindOfClass:[NativeRenderWaterfallView class]], @"view must be kind of NativeRenderWaterfallView"); if ([view isKindOfClass:[NativeRenderWaterfallView class]]) { view.dirtyContent = YES; - view.changeContext = [context copy]; + view.changeContext = context; [view pushDataSource:dataSource]; } }; diff --git a/renderer/native/ios/renderer/component/waterfalllist/NativeRenderWaterfallView.mm b/renderer/native/ios/renderer/component/waterfalllist/NativeRenderWaterfallView.mm index 5e93bd257e6..3cc9d27a35a 100644 --- a/renderer/native/ios/renderer/component/waterfalllist/NativeRenderWaterfallView.mm +++ b/renderer/native/ios/renderer/component/waterfalllist/NativeRenderWaterfallView.mm @@ -67,7 +67,7 @@ - (instancetype)initWithFrame:(CGRect)frame { _scrollEventThrottle = 100.f; _weakItemMap = [NSMapTable strongToWeakObjectsMapTable]; _cachedItems = [NSMutableDictionary dictionaryWithCapacity:32]; - _dataSourcePool = [NSMutableArray arrayWithCapacity:8]; + _dataSourcePool = [NSMutableArray array]; _dataSourceSem = dispatch_semaphore_create(1); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; [self initCollectionView]; From b4ea14c896aecd5d96cc015e80a5b590a5e5d992 Mon Sep 17 00:00:00 2001 From: wwwcg Date: Thu, 26 Oct 2023 23:26:21 +0800 Subject: [PATCH 2/3] fix(ios): listview performance optimization and bug fix p2 --- .../component/listview/NativeRenderBaseListViewDataSource.mm | 1 + .../component/waterfalllist/NativeRenderObjectWaterfall.mm | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/renderer/native/ios/renderer/component/listview/NativeRenderBaseListViewDataSource.mm b/renderer/native/ios/renderer/component/listview/NativeRenderBaseListViewDataSource.mm index 032d9f7fb59..0c983002771 100644 --- a/renderer/native/ios/renderer/component/listview/NativeRenderBaseListViewDataSource.mm +++ b/renderer/native/ios/renderer/component/listview/NativeRenderBaseListViewDataSource.mm @@ -173,6 +173,7 @@ - (void)applyDiff:(NativeRenderBaseListViewDataSource *)another if (context.allChangedItems.count > 1) { [view reloadData]; completion(YES); + return; } // The following logic is not perfect and needs to be further refined diff --git a/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.mm b/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.mm index 2b4ad5a2a2a..557ca06b885 100644 --- a/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.mm +++ b/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.mm @@ -94,7 +94,8 @@ - (void)appendFrameChangedItem:(__kindof HippyShadowView *)objectView { } - (BOOL)hasChanges { - return _addedItems.count != 0 || _deletedItems.count != 0 || _movedItems.count != 0 || _frameChangedItems.count != 0; + return _addedItems.count != 0 || _deletedItems.count != 0 || + _movedItems.count != 0 || _frameChangedItems.count != 0; } - (NSSet *)allChangedItems { From e874e21caac1471e3e305f01b76c03eedfe133b0 Mon Sep 17 00:00:00 2001 From: wwwcg Date: Mon, 30 Oct 2023 17:13:51 +0800 Subject: [PATCH 3/3] fix(ios): fix listview amendLayoutBeforeMount bug --- .../waterfalllist/NativeRenderObjectWaterfall.mm | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.mm b/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.mm index 557ca06b885..cd44539eb60 100644 --- a/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.mm +++ b/renderer/native/ios/renderer/component/waterfalllist/NativeRenderObjectWaterfall.mm @@ -175,10 +175,8 @@ - (void)itemFrameChanged:(__kindof NativeRenderObjectWaterfallItem *)item { } - (void)amendLayoutBeforeMount:(NSMutableSet *)blocks { - if ([self isPropagationDirty:NativeRenderUpdateLifecycleLayoutDirtied]) { - if (!_itemChangeContext.hasChanges) { - return; - } + if ([self isPropagationDirty:NativeRenderUpdateLifecycleLayoutDirtied] && + _itemChangeContext.hasChanges) { WaterfallItemChangeContext *context = [_itemChangeContext copy]; NSArray *dataSource = [self.subcomponents copy]; __weak __typeof(self)weakSelf = self; @@ -196,9 +194,9 @@ - (void)amendLayoutBeforeMount:(NSMutableSet *)blocks } }; [blocks addObject:block]; + [_itemChangeContext clear]; } [super amendLayoutBeforeMount:blocks]; - [_itemChangeContext clear]; } @end