I saw that 3.0.0 was available for download today. I installed it in one of our apps. The side drawer works fine. But, the RadListView is throwing an exception with angular2.
I've attached a screenshot of the error. I have removed almost everything from the template. In fact, I used the HTML code from the docs site.
This is the code from the docs site, with only the [items] changed.
<GridLayout tkExampleTitle tkToggleNavButton row="2" col="0" #showContainer id="showContainer">
<RadListView [items]="shows">
<ng-template tkListItemTemplate let-item="item">
<StackLayout orientation="vertical">
<Label class="nameLabel" [text]="item.name"></Label>
<Label class="descriptionLabel" [text]="item.description"></Label>
</StackLayout>
</ng-template>
</RadListView>
</GridLayout>
I'm using the latest version of nativescript. tns doctor shows no updates. tns update was run minutes ago.
3 Answers, 1 is accepted
Based on the snippet you have used I have created this brand new Angular based application and was able to use RadListView as expected. However, I have some suggestions that might help you resolve your issue.
The first thing we can check is to make sure that apart from updating the plugin version you have also updated to the latest tns-core-modules version. You can use as a reference the package.json file from our sample Angular application. In your project, the version of tns-core-modules should as on this line.
You can also check the Angular related dependencies either from my test application or again from our sample Angular project.
After updating the versions, make sure you have your old node_modules deleted and then run new install or directly rebuild the project
rm -rf node_modules platforms
npm install
tns run android
If this is already done or the above suggestion does not resolve your issue then you can try to further isolate the issue by removing all CSS classes and leaving only the RadListView with the initial source items. I would also suggest checking out the list of breaking changes and make sure that your application complies with all of them
I hope you will find the above information useful - if however, you are still experiencing issues after the update please send us your package.json content along with the code responsible for the items created and the CSS styles (virtually everything related to the RadListView that is throwing is needed) or if possible you can send us sample project demonstrating the issue (no node_modules and platforms folders are needed)
Regards,
Nikolay Iliev
Progress Telerik
It was the tns-core-modules version. Thank you.
I am also having a performance issue. You can find the code to replicate it here: https://github.com/simplec-dev/radlistview-performance
It works reasonably well on an x86 emulator. When I put it on an actual android device, the performance is bad. First, it takes a while to render - my actual app navigates to a page like this and it hangs for 2-5 seconds. Second, once it is rendered, the first scroll lags by 1-2 seconds.
I've been playing with it for about a week and can't get it to perform better.
Some things I have noticed:
1) linear layout doesn't have the same problem
2) I have tried using itemWidth and itemHeight to give the rendering process a hint. It has no affect visually or with performance.
3) I added height to the top level css "show-tile" and it had no affect on performance
4) I tried the webpack aot compile and it didn't affect performance
Any help would be appreciated.
Thank you for the GutHub link and the test project - however, the project is not showing us how you are navigating from one page to another and also it is not exactly clear what is happing on this tap (where we suspect the navigation is happening and the where the performance bottleneck is happening).
However, I can give you some optimization techniques tips based on your HTML layout.
- The first thing that I have noticed is the excessive usage of structural layouts like StackLayout.
This is bad practice for performance because even if the layouts are empty containers they are in fact re-drawn on each page load. This said - the more layout you have the more operations will be executed and the slower you page will render. This is crucial to avoid in the context of mobile development where some devices are still with limited operating resources (e.g. with 512MB memory or less).
So instead of using multiple layout containers e.g.:
<
StackLayout
class
=
"a"
>
<
StackLayout
class
=
"b c"
>
<
Label
><?
Label
>
</
StackLayout
>
</
StackLayout
>
You can simplify the layout and make it much more performance optimized (even crucial for repeating temp[altes like the ones used in ListView and in RadListView) e.g.:
<
Label
class
=
"a b c d"
><?
Label
>
The overall rule of thumbs is that even the most complex designs should be achieved with no more than three levels of nesting (when possible of course). Instead of using "heavy" layouts for containers just to assign a specific class. remove as many as possible layouts and use CSS classes to achieve the UI you want.
So in your case yu can simplify the ng-template used for each list like this:
<
RadListView
[items]="items" #showContainer
id
=
"showContainer"
>
<
ng-template
tkListItemTemplate
let-item
=
"item"
>
<
GridLayout
class
=
"{{item.tileClass}} {{item.selectedClass}}"
columns
=
"*"
rows
=
"auto, auto, *, auto"
>
<
Label
class
=
"gothic-medium text-center {{item.topClass}}"
text
=
"{{item.topText}}"
row
=
"0"
col
=
"0"
></
Label
>
<
FrescoDrawee
row
=
"1"
col
=
"0"
class
=
"show-tile-thumb"
imageUri
=
"{{item.absoluteThumb}}"
actualImageScaleType
=
"centerCrop"
></
FrescoDrawee
>
<
Label
row
=
"1"
col
=
"0"
class
=
"gothic-medium show-tile-thumb-overlay"
text
=
"{{item.overlayText}}"
verticalAlignment
=
"top"
[visibility]="item.overlayText!=null ? 'visible' : 'collapsed'"></
Label
>
<
GridLayout
row
=
"1"
col
=
"0"
rows
=
"1*,1*,1*"
columns
=
"auto,*,auto"
class
=
"show-tile-thumb-size"
>
<
Image
row
=
"0"
col
=
"2"
class
=
"overlay-icon"
stretch
=
"aspectFit"
src
=
"~/img/button/completed-overlay.png"
horizontalAlignment
=
"right"
verticalAlignment
=
"top"
[visibility]="item.completed ? 'visible' : 'collapsed'"></
Image
>
<
Image
row
=
"0"
col
=
"1"
class
=
"overlay-icon"
stretch
=
"aspectFit"
src
=
"~/img/button/empty.png"
horizontalAlignment
=
"left"
verticalAlignment
=
"bottom"
></
Image
>
<
Image
row
=
"1"
col
=
"1"
class
=
"overlay-icon"
stretch
=
"aspectFit"
src
=
"~/img/button/empty.png"
horizontalAlignment
=
"left"
verticalAlignment
=
"bottom"
></
Image
>
<
Image
row
=
"2"
col
=
"1"
class
=
"overlay-icon"
stretch
=
"aspectFit"
src
=
"~/img/button/empty.png"
horizontalAlignment
=
"left"
verticalAlignment
=
"bottom"
></
Image
>
<
Image
row
=
"2"
col
=
"0"
class
=
"overlay-icon"
stretch
=
"aspectFit"
src
=
"~/img/button/calming-overlay.png"
horizontalAlignment
=
"left"
verticalAlignment
=
"bottom"
[visibility]="item.calming ? 'visible' : 'collapsed'"></
Image
>
<
Image
row
=
"2"
col
=
"2"
class
=
"overlay-icon"
stretch
=
"aspectFit"
src
=
"~/img/button/trusted-voice-overlay.png"
horizontalAlignment
=
"right"
verticalAlignment
=
"bottom"
[visibility]="item.includesVoice ? 'visible' : 'collapsed'"></
Image
>
</
GridLayout
>
<
Label
row
=
"2"
col
=
"0"
class
=
"gothic-medium show-tile-text show-tile-name"
text
=
"{{item.name}}"
></
Label
>
<
Label
row
=
"3"
col
=
"0"
class
=
"show-tile-button {{item.buttonClass}} gothic-medium"
(tap)="selectShow(item)"
horizontalAlignment
=
"center"
text
=
"{{item.startButtonLabel}}"
></
Label
>
</
GridLayout
>
</
ng-template
>
<
ListViewGridLayout
tkListViewLayout
scrollDirection
=
"Vertical"
spanCount
=
"{{spanCount}}"
></
ListViewGridLayout
>
</
RadListView
>
I have removed a bunch of empty stack layouts where possible and with some additional CSS styles, the same effect can be achieved from UX point of view.
- Another possibility that may cause a performance bottleneck is the excessive usage of images. TO resolve this you can try the techniques described in this article/ For example using loadMode to async will prevent the UI from being blocked while the images are loaded from online resources.
- yet another thing to consider when testing your Angular based application is the number of modules you application is using. For larger and heavier applications we would recommend using Lazy Loading as optimization technique as done in this sample application. The linked app has more than 200 loaded modules and its overall performance is very good when building for release with WebPack.
- and the last tip - test your application performance with a release build and not with debug build. The release builds are considerably faster and optimized (especially when using Webpack) while the debug builds are meant to be easier for testing and debugging but they do have overall slower performance.
Regards,
Nikolay Iliev
Progress Telerik