4

I have RadSideDrawer in many pages of my Nativescript application. Main app component has a page-router-outlet and all other pages are loaded into this component with navigation. Pages with drawer contains a RadSideDrawer component around page content.

The problem is RadSideDrawer freezes when navigating between pages. You can see it here:

RadSideDrawer freezes

RadSideDrawer transition is not smooth. But when I install the angular nativescript ui samples angular application drawer transitions are very smooth:

ui sample is smooth

zarax
  • 871
  • 1
  • 10
  • 30
  • Post the HTML for your RadSideDrawer and any code-behind that interacts with it - look for excessive usage of Angular structural directives (like *ngIf) and try to minimize their usage (e.g use visibility) – Nick Iliev Nov 07 '17 at 15:13
  • 1
    RadSideDrawer html code is very small and only has one ngFor. Main performance problem is that almost all pages navigated to contains a list of elements. Nativescript needs to render the list ui and it makes the app freeze for a short amount of time. I put a 100 ms delay between data received from server and it set to ui so that ui will start to render 100 ms after page navigation. In that time RadSideDrawer closes smoothly. – zarax Nov 13 '17 at 09:44
  • I think Nativescript takes too much time to render UI. – zarax Nov 13 '17 at 09:45
  • @zarax If your rendering a lot of data on page load/navigation have you tried moving the loading into a worker if possible or just loading a subset of items first? I have found that Nativescript isn't that mush slower than native for things like this (note: i do nativescript vanilla and not angular so your mileage may vary) – Roland Nov 14 '17 at 05:49
  • @Roland I don't render to much data. Just a list of items. There is no cpu intensive operation when preparing that list. I just take it from server and show it. I already use RadListView. As far as I know, it only renders items that are visible in the screen. So even if list contains 50 items it will render 5 or 6 of them. But as you can see list items are not just text items. They contain some labels. – zarax Nov 14 '17 at 10:57
  • @zarax could the lag be due to getting the data from the server? Aka if it takes 500ms then there would be 500ms delay before the rest of your code executes? (Just guessing since i dont know how you have organised your code). Also try navigating to a simple page that doesn't load anything (such as a page with just a couple of hard coded buttons and text) to see if the lag is still there – Roland Nov 14 '17 at 22:02
  • @Roland Delay in http requests have no effect on application performance as in javascript, http requests don't block code execution. Pages are not simple pages. They contain list views. Items in the list have other elements. Because of that it is not a simple list of strings. Main problem seems to be rendering problem. It takes too much time to render page and it freezes the app. – zarax Nov 15 '17 at 21:18

1 Answers1

0

I think that the best approach is to delay access to data inside a rendered component so navigation (and animation) from RadSideDrawer can complete. Then when data is accessible, rendering of a component starts.

If you mix RxJS delay operator (assuming you get data using Observable) with ActivityIndicator - you can get quite good results.

Below is one of many possible solutions.

TS file:

import { Component, OnInit } from "@angular/core";
import { Observable } from "rxjs";
import { EventItem } from "../../../../models/event-item.model";
import { AppStateFacadeService } from "../../../../services/app-state-facade.service";
import { delay } from "rxjs/operators";

@Component({
    selector: "Test",
    moduleId: module.id,
    templateUrl: "./test.component.html",
    styleUrls: ["./test.component.css"]
})
export class TestComponent implements OnInit {
    events$: Observable<Array<EventItem>>;

    constructor(private appStateFacade: AppStateFacadeService) {}

    ngOnInit(): void {
        this.events$ = this.appStateFacade.getEvents().pipe(delay(400));
    }
}

HTML file:

<StackLayout *ngIf="events$ | async as events; else nocontent">
    <ListView class="list-group" [items]="events">
        <ng-template let-event="item">
            <EventItem [eventItem]="event"></EventItem>
        </ng-template>
    </ListView>
</StackLayout>
<ng-template #nocontent>
    <ActivityIndicator row="1" #activityIndicator busy="true" width="100" height="100" class="activity-indicator">
    </ActivityIndicator>
</ng-template>
Sebastian Denis
  • 928
  • 10
  • 20