1

I have run into a performance issue - I can not seem to solve.

Basically I have this dynamic table like structure that works like this

<div class="container">
  <div *ngFor="let column of columnData">
    <div *ngFor="let rowItem of column.rowItems">
      <div [innerHTML]="getHtml(rowItem.info)"></div>
    </div>
  </div>
</div>

in my component I have a function that takes the rowItem data and then returns some html markup like so

getHtml(data) {
  if (...) {
    return `
      <div>
        ...
      </div>
    `
  } else if {
    return `
      <svg>
        ...
      </svg>
    `
  } else {
    ...
  }
}

now my data structure is as follows

columnData = [
  {
    columnHeader: 'test'
    rowItems: [
      {
         rowHeader: 'test',
         value: 1
      },
      // ...
    ]
  },
  // ...
]

so there may be 100 columns, and each column has 25 rowItems - now the rowItems are almost identical except for the value + some other values I havent displayed but for example the rowHeader always stays the same.

so for the layout to display correctly, we need to loop through each column and also loop through each rowItem - so this becomes a nested for loop. Now with a small amount of data this works fine - but we have quite a lot of data and some objects have 100 columns and 50 rows, so this slows the site down quite considerably - this is the performance

enter image description here

as you can see quite a lot of scripting, now when I remove the nested for loop I get the following

enter image description here

a considerable improvement, but obviously I still need to be able to generate the rowItems.

I have tried using a virtual list - but it is still quite laggy / buggy as it scrolls.

What generally happens is as im scrolling horizontally the whole screen will go white and ill get this warning in the browser

enter image description here

I have also tried progressive rendering, where I only render 10 columns at a time, but this still isnt very performant.

Is there anything else I can do?

Any help would be appreciated

As suggested I tried to implemenet trackBy like so

<div class="container">
  <div *ngFor="let column of columnData; trackBy: columnTrackByFn">
    <!-- ... -->
    <div *ngFor="let rowItem of column.rowItems; trackBy: rowTrackByFn">
      <!-- ... -->
    </div>
  </div>
</div>
columnTrackByFn(index, item) {
  return item.colId;
}

rowTrackByFn(index, item) {
  return item.rowId;
}

and it didnt help, if anything is made it slower

enter image description here

Smokey Dawson
  • 8,827
  • 19
  • 77
  • 152
  • 1
    Have you tried trackBy: check this:https://netbasal.com/angular-2-improve-performance-with-trackby-cc147b5104e5 – Chellappan வ Jul 01 '20 at 06:18
  • @Chellappanவ I have updated my question, it didnt seem to help.. did I implement it correctly? – Smokey Dawson Jul 01 '20 at 06:30
  • For this best solution is virtual scrolling, but as you said its laggy for you I think you should check your implementation again. Check https://medium.com/front-end-weekly/how-to-use-virtual-scrolling-using-angular-7-cdk-9802110111fa. – vaibhavmaster Jul 01 '20 at 06:44
  • @vaibhavmaster my issue is that my virtual scroll, needs to scroll horizontally - and the cdk and ngx-virtual-for dont seem to support this very well - not only that for each rowItem i need to render some html so all of this really affects the performance of the virtual scroll – Smokey Dawson Jul 01 '20 at 07:04
  • Post what you do inside your ngFor within the We have loops like these without any performance problems. The performance hit is in what you do within – Max Jul 01 '20 at 08:24
  • @Max i have updated the question - within each rowItem loop it is calling a function that returns some html markup – Smokey Dawson Jul 01 '20 at 12:16
  • Hi You have implemented trackBy correct only, I am not sure why it's taking too long to paint, check this post it might help:https://stackoverflow.com/questions/41218507/violation-long-running-javascript-task-took-xx-ms – Chellappan வ Jul 02 '20 at 12:15
  • @Chellappanவ my only thought is the rowId is not unique, for each column there will be a rowItem withe same ID, could this be causing any issues? – Smokey Dawson Jul 04 '20 at 05:44
  • Could be. If row is not unique, can you try track with index? – Chellappan வ Jul 04 '20 at 05:55
  • @Chellappanவ using the index for the trackBy has definitely speed it up – Smokey Dawson Jul 05 '20 at 23:53
  • @SmokeyDawson yeah, that `
    ` is suspect too. Any way you could move the getHtml() into a normal data binding so you don't call a function?
    – Max Jul 12 '20 at 09:46

0 Answers0