How to render a component in a cell with better performance ?

Posted by: rizwan on 14 January 2020, 5:52 am EST

  • Posted 14 January 2020, 5:52 am EST

    Currently I am using following code in my wrapper component to render data.

    <wj-flex-grid #grid [(itemsSource)]="dataSource" (initialized)="gridReady(grid, $event)" headersVisibility="Column">
    <wj-flex-grid-filter #filter></wj-flex-grid-filter>
    <wj-flex-grid-column *ngFor="let col of colums.items"
    [header]="col.header"
    [binding]="col.binding"
    [allowSorting]="col.allowSorting"
    [format]="col.format">
    <ng-container *ngIf="col.customCell">
    <ng-template wjFlexGridCellTemplate [cellType]="'Cell'" let-cell="cell">
    <ng-container *ngComponentOutlet="col.customCell; injector: createInjector(cell); "></ng-container>
    </ng-template>
    </ng-container>
    </wj-flex-grid-column>
    </wj-flex-grid>

    I am using 'ngComponentOutlet' to render the component dynamically which i receive from colum definition which is my custome object given below

    colDef: {
    header: "Location",
    allowSorting: true,
    allowFilter: true,
    customCell: SomeComponent
    width: '100'
    };

    For just 50 records, the UI stucks for a moment. Can you please guide me if how can i improve its performance or is there any better way of doing this?
  • Replied 14 January 2020, 3:18 pm EST

    Hi Rizwan,

    We are sorry but we were not able to replicate the issue at our end. Please refer to the sample below that we used to replicate the issue:

    https://stackblitz.com/edit/angular-3gprvr

    Could you please let us know whether we are missing something in order to replicate the issue? You may also modify the sample accordingly so that it replicates the issue.

    Regards,
    Ashwin
  • Replied 14 January 2020, 6:31 pm EST

    I am trying to reproduce this issue on stackblitz. I have noticed another issue. anchor tag not working inside of cell. when i click, nothing happens. please have a look on below example.

    My full wrapper component which i am using in a project and having UI issue. Please suggest if i can do dynamic component rendering better than this.
    https://stackblitz.com/edit/wijmo-wrapper-dynamic-cell
  • Replied 15 January 2020, 1:37 am EST

    I have tried to do this using wj-component-loader and its performance is a bit better but problem is custom cell component cells do not update even data source changes on pagination. here is my code

    <ng-template *ngIf="col.customCell" wjFlexGridCellTemplate [cellType]="'Cell'" let-cell="cell">
    <wj-component-loader [component]="col.customCell" [properties]="{cell: cell.item}"></wj-component-loader>
    </ng-template>

    Interesting thing is that other columns do update on pagination or when data source changes. Please suggest.
  • Replied 15 January 2020, 8:04 pm EST

    Hi Rizwan,

    Thank you for the sample.

    I updated the provided sample to use WjComponentLoader to load the components. I also updated the FFIdFormatterComponent class to use the ID provided and update the view accordingly. It is working even if we change the page or the data source.

    Regarding the performance, even while using the ngComponentOutlet to load components, the performance in my machine was good. The UI was stuck but only for a fraction of seconds. If you will run the sample in production mode, UI will never get stuck. Below is my machine configuration:

    OS: Windows 10
    Ram: 12Gb DDR3
    Processor: i7-3370 @ 3.40GHz
    Browser: Chrome 79

    Regarding the anchor tag, the clickSearch method was called without changing anything.

    Refer to the sample attached and let me know if there are still any issues.

    ~regards

    sample.zip
  • Replied 16 January 2020, 7:22 pm EST

    Thanks ashwin for your changes. I just need to understand oninit and ondestroy flow. I have attached the image and updated that stackblitz example.
    https://stackblitz.com/edit/wijmo-wrapper-dynamic-cell

    Please help me understand why IdFormatterComponent is being destroyed right after init. Because i can not figure out the pattern it follows for custom components rendering. You can comment the destructor and click on custom component i.e. id. and it starts giving some weird pattern in console logs.

    Note:
    [autoRowHeights]="true"
    i need to set this property in my real application because if i dont do this then:
    -> grid is first rendered with default row size truncating my custom comp items.
    -> then after some seconds it is redrawn with what we want.
    but by setting it to true oninit of custom component is being called twice. For example, if i render 50 rows its total count becomes 100. But When this flag is set to false, although design is disturbed for some time but oninit does not get called twice.



  • Replied 19 January 2020, 10:32 pm EST

    Hi Rizwan,

    I have asked the dev team on why the component is initialized and destroyed multiple times. The internal tracking id of the case is 417659.

    Regarding autoRowHeights, this is expected because autoRowHeights property works after the grid have been loaded. You could try using the autoSizeRows property of WjFlexGridCellTemplate. This will automatically resize the rows according to the data:
    <ng-template wjFlexGridCellTemplate [cellType]="'Cell'" let-cell="cell" [autoSizeRows]="true">
    <ng-container *ngComponentOutlet="col.customCell; injector: createInjector(cell); "></ng-container>
    </ng-template>


    ~regards
  • Replied 20 January 2020, 8:43 pm EST

    Hi Ashwin,
    Thanks for looking into the issue. I am waiting for dev team and yours response on it.

    I have tried with autoSizeRows and it has disturbed styling of my actual component.

    The most important issue now is, when i render more than two dynamic components with some styling on .wj-cell and .wj-header, the UI and grid hangs and does not work as it should. I have replicated the issue in the following stackblitz demo. Please have a look. Waiting for your quick response as i am using enterprise version and new to wijmo so i am having a lot of issues.

    https://stackblitz.com/edit/wijmo-wrapper-dynamic-cell
  • Replied 21 January 2020, 8:09 pm EST

    Hi again,

    Regarding the performance, this is expected because you are adding a new component for each of the rows and since there are many number of rows, there are multiple components loaded on a single page due to which the performance is degraded. If you will reduce the number of cells shown on the DOM, by decreasing the dimensions of the FlexGrid or by applying paging, the performance will increase. Also, the angular change detection runs twice in the development mode for every detect cycle. So, performance will also increase if you will use the production mode of angular.

    If you are still worried about the performance, then you can use the CellFactory class to add the components. You may refer to the sample link below for implementing CellFactory in FlexGrid:

    https://demos.wijmo.com/5/SampleExplorer/SampleExplorer/Sample/CellFactory

    You will have to implement the CellFactory using Typescript, so you will need to use the createComponent method of ViewContainerRef. You can read more about it here:

    https://angular.io/guide/dynamic-component-loader

    ~regards
  • Replied 26 January 2020, 11:15 pm EST

    Hi,
    I am trying to use custom cell factory. It seems faster but i am unable to render custom components using wj-component-loader or ngComponentOutlet. Can you please share an example that uses custom cell factory and generate dynamic component just like i was doing in my above stackblitz example? so i can use it as a reference
  • Replied 27 January 2020, 6:34 pm EST

    Hi Rizwan,

    If you will custom CellFactory, you will need to remove all the column definitions from the HTML template and you will also need to create columns in the TS file. Could you please confirm whether these changes can be applied at your end so that I could provide you with a sample along with all the changes?

    ~regards
  • Replied 29 January 2020, 4:22 pm EST

    Hi Ashwin,
    I think yes, a sample would be really helpful. :)
  • Replied 30 January 2020, 10:51 pm EST

    Hi Rizwan,

    I will provide you with the sample on Monday.

    ~regards
  • Replied 2 February 2020, 10:33 pm EST

    Hi Rizwan,

    Please refer to the sample attached.

    In this sample, I have removed all the component loaders from the ff-advanced-wijmo-grid.component.html file and only columns are generated in the template. Also in the ff-advanced-wijmo-grid.component.ts file, I have created override the updateCell method of CellFactory to load the components using TS.
    If we will load the components in the TS file, angular will not have to compile the ng-template in the component's HTML file and thereby increasing the performance a little bit.
    Please try to implement this at your end and let us know if the performance increases.

    ~regards

    component_cell_factory.zip
  • Replied 6 February 2020, 6:07 pm EST

    Thanks for sharing this code. I have integrated this code in my code but i am having a weird scenario.
    constructor(@Inject(DynamicData) public params: any) {
    this.BASE_URL = APP_CONSTANTS.BASE_URL;
    }


    i am receiving this data like this in my dynamic component. Although in console.log i am getting params value exactly what i need i.e. which is passed using
    const viewRef = factory.create(self.createInjector(item));
    in your sample. But it is not being rendered on cell. Seems like binding with params is not working because when i put some hard coded text in that dynamic component, it renders but i need that params data to be rendered there. Please suggest.

    i have re-produced it in my stackblitz example as well

    https://stackblitz.com/edit/wijmo-wrapper-dynamic-cell?file=src%2Fapp%2Fwijmo-grid%2Fff-advanced-wijmo-grid%2Fff-id-formatter.component.ts
  • Replied 9 February 2020, 9:07 pm EST

    Hey Rizwan,

    In the custom component, the projectsLists returned the correct data but it was now shown properly on the FlexGrid because the overflow of the cells of the grid is hidden and therefore the projectsLists div is shown inside the cell, due to which it becomes very small to be noticed. Since, we cannot change the overflow of the cells, you may use the Wijmo's Popup control to show the list. Please refer to the updated sample below:

    https://stackblitz.com/edit/wijmo-wrapper-dynamic-cell-8v9ub7

    In this sample, I have changed the template of both the Custom components and also some CSS.

    ~regards
  • Replied 10 February 2020, 8:44 pm EST

    Hi Ashwin,

    Your example does not include custom cell factory. Previously you shared a zip that includes what i was looking for but i was unable to render dynamic data into custom cells. This stackblitz is following the old way which was creating performance issue not the custom cell factory that you suggested. Please update it accordingly.
  • Marked as Answer

    Replied 12 February 2020, 3:35 pm EST

    Hi Rizwan,

    Sorry for the delayed response. I have updated the sample accordingly. While creating the component in the CellFactory, you will need to explicitly pass the params data to the custom component. Also, you will need to call the detectChanges method to detect the changes manually.

    ~regards

    sample.zip
  • Replied 12 February 2020, 4:41 pm EST

    Thanks Ashwin :) your solution was really helpful.
  • Replied 12 February 2020, 6:40 pm EST

    I also got it working by only making following change
    const viewRef: any = factory.create(self.createInjector(item));
    cell.appendChild((viewRef.hostView as EmbeddedViewRef<any>).rootNodes[0]);
    viewRef.changeDetectorRef.detectChanges();
  • Replied 12 February 2020, 7:40 pm EST

    Hi again,

    Glad to be able to help and thanks for a different solution.

    ~regards
Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels