Problem:
I have an angular-nativescript app that needs to display some items in a grid. I'm using a RadListView to render the list and after upgrading my angular, {N}, and other library dependencies over the last few months I've noticed the RadListView rendering of the items has gotten unbearably slow. I have multiple "tabs" so you can see different types of items and whenever you switch "tabs" it needs to completely re-render the list with the new times. Before doing some upgrades (which I had hoped would improve app performance) switching tabs would have no significant lag even for rendering 100+ items. Now it takes several seconds to load even 24 (I switched to dynamic rendering on scroll to speed things up but it isn't nearly good enough).
Platform info:
- ios (tns ios 5.2.0, 5.3.1) [Angular 7]
- nativescript-ui-listview: 6.1.0
- nativescript-ui-core: 2.0.1
- nativescript-ui-sidedrawer: 6.0.0
- CLI: 5.3.1
- Cross-platform modules: 5.3.1
- Runtime(s): tns-ios 5.3.1
The issue appears to be related to having some nested structures w/in a RadListView. My original code (which ran was unchanged since performing just fine on older versions of {N}, Angular, nativescript-ui:
<RadListView id="itemList" top="0" left="0" [items]="displayedInventory" separatorColor="white" [loadOnDemandMode]="loadOnDemandMode"
(loadMoreDataRequested)="onLoadMoreItemsRequested($event)" class="gridview-wrap-tabs" dock="top" [ngClass]="{'gridview-wrap-tabs': (posLocation && posLocation.tabs)}">
<ListViewStaggeredLayout tkListViewLayout scrollDirection="Vertical" spanCount="4" itemHeight="180" horizontalAlignment="left"
class="inventory-list-view-inner" separatorColor="black">
</ListViewStaggeredLayout>
<ng-template tkListItemTemplate let-item="item">
<StackLayout class="inventory-stack-wrap">
<GridLayout rows="auto, *, auto" columns="auto, auto" orientation="horizontal" class="outerBox" stretchLastChild="true" (tap)="addToCart(item, true)"
[ngClass]="{ 'portraitBox': orientation==='portrait' , 'selected-inventory-item': item.isSelected, 'empty-inventory-item': item.price < 0}">
<Label row="0" col="0" *ngIf="item.type==='category'" height="40px" class="price-label-category" [ngClass]="{ 'portrait-category-label': orientation==='portrait' }"
text="Category"></Label>
<Label row="1" col="0" verticalAlignment="top" [text]="item.name" *ngIf="item.type==='category'" class="name-label" textWrap="true"
[ngClass]="{ 'portrait-name-label': orientation==='portrait' }"></Label>
<Label row="0" col="0" verticalAlignment="top" [text]="item.name" *ngIf="item.name && item.name.length <=2 0 && item.type !=='category'"
class="name-label" textWrap="true" [ngClass]="{ 'portrait-name-label': orientation==='portrait' }"></Label>
<Label row="0" col="0" verticalAlignment="top" [text]="item.name.slice(0,20) + '...'" *ngIf="item.name
&& item.name.length> 20 && item.type !== 'category'" class="name-label" textWrap="true" [ngClass]="{'portrait-name-label': orientation
=== 'portrait'}"></Label>
<GridLayout col="0" colSpan="2" row="1" rowSpan="2" width="100%" *ngIf="item.imageSource">
<Image class="inventory-image" [ngClass]="{'portrait-inventory-image': orientation==='portrait'}" [src]="item.imageSource"></Image>
</GridLayout>
<GridLayout width="100%" *ngIf="item.type !=='category'" row="2" col="0" colSpan="2" columns="auto, *, 10" rows="auto">
<Label col="1" row="0" horizontalAlignment="right" height="40px" class="price-label" [ngClass]="{ 'portrait-price-label': orientation==='portrait' }"
text="${{item.price | number: '1.2-2'}}"></Label>
</GridLayout>
</GridLayout>
</StackLayout>
</ng-template>
</RadListView>
As a proof of concept to verify that the RadListView rendering is what was slowing it down, I tried it with a just a single label with the item's name embedded in the and the rendering was pretty much instant - so it appears to be a problem with how the RadListView is rendering subitems like StackLayout, GridLayout. I also tried replacing the GridLayout with a DockLayout and removing all the angular *ngIfs and *ngClasses (and removed the Image tag) to see if that would improve performance but it didn't appear to have any effect. Still extremely slow to load just 24 items. (Loading does go up significantly for fewer items - but I can't display fewer than 24 initially)
Any ideas? I'd prefer to not have to downgrade my angular and nativescript dependencies
I was able to significantly improve the load time by switching from using a ListViewStaggeredLayout to a ListViewGridLayout. The issue wasn't around in earlier versions of {N} and angular so it looks like an update somewhere along the way caused it to lag.