Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug(Table): Polling data causes memory leak #30300

Open
1 task
conalryan opened this issue Jan 9, 2025 · 0 comments
Open
1 task

bug(Table): Polling data causes memory leak #30300

conalryan opened this issue Jan 9, 2025 · 0 comments
Labels
needs triage This issue needs to be triaged by the team

Comments

@conalryan
Copy link

conalryan commented Jan 9, 2025

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

If you poll for data then you will get Detached nodes each time the table refreshes. A workaround is to add trackBy and the memory leak stops. However, is this behavior expected when polling without trackBy?

Reproduction

StackBlitz link: https://stackblitz.com/edit/stackblitz-starters-sdd99umf?file=src%2Fmain.ts
I had a hard time seeing it in stackblitz however, I have a github repo where it can be reproduced.

Github repo: https://github.com/conalryan/angular-material-table-memory-leak/tree/master

  1. npm install && npm run start
  2. Take a memory shot
  3. Wait a few minutes and take another snapshot.

Here's the code

import { CdkTableModule } from '@angular/cdk/table';
import { Component, OnInit } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { map, Observable, tap, timer } from 'rxjs';

export interface SimpleData {
  id: number;
  name: string;
}

export const SIMPLE_DATA: SimpleData[] = [
  { id: 1, name: 'John Doe' },
  { id: 2, name: 'Jane Smith' },
  { id: 3, name: 'Alice Johnson' },
  { id: 4, name: 'Bob Brown' },
  { id: 5, name: 'Charlie Davis' },
];

@Component({
  selector: 'table-memory-leak',
  imports: [CdkTableModule],
  template: `
    <h3>Table Memory Leak</h3>
    <table cdk-table [dataSource]="dataSource">
      <ng-container cdkColumnDef="id">
        <th cdk-header-cell *cdkHeaderCellDef>ID</th>
        <td cdk-cell *cdkCellDef="let row">{{ row.id }}</td>
      </ng-container>

      <ng-container cdkColumnDef="name">
        <th cdk-header-cell *cdkHeaderCellDef>Name</th>
        <td cdk-cell *cdkCellDef="let row">{{ row.name }}</td>
      </ng-container>

      <tr cdk-header-row *cdkHeaderRowDef="['id', 'name']"></tr>
      <tr cdk-row *cdkRowDef="let row; columns: ['id', 'name']"></tr>
    </table>
  `,
  styles: `
    table {
      margin: 0 auto;
      table-layout: fixed;
      width: 800px;
    }
  `,
})
export class TableMemoryLeakComponent implements OnInit {
  displayedColumns: string[] = ['id', 'name'];
  dataSource = new MatTableDataSource<SimpleData>();
  
  ngOnInit() {
    this.#poll().subscribe((res) => {
      this.dataSource.data = res;
    });
  }

  trackByFn(index: number, item: SimpleData) {
    return item.id;
  }

  #poll(ms = 2500): Observable<SimpleData[]> {
    // Simulating periodic refreshes (every few seconds the REST endpoint can be executed to update the view without user refreshing)
    return timer(0,ms).pipe(
      /**
       * This is just to simulate creating new JS objects.
       * This is the case when you have here a REST call to backend.
       * Without that, Angular just knows this is exactly the same JS object, so it won't repaint anything.
       */
      tap(_ => console.log('[table-service]::fetch')),
      map(_ => JSON.parse(JSON.stringify(SIMPLE_DATA))));
  }
}

Expected Behavior

Using TrackBy there is no leak. Should that be the case without trackBy?

Memory 3

Memory 4

Actual Behavior

Detached increases over time

Memory 1

Memory 2

Environment

  • Angular: 19.0.4
  • CDK/Material: 19.0.4
  • Browser(s): Chrome 131.0.6778.206
  • Operating System (e.g. Windows, macOS, Ubuntu): Mac
@conalryan conalryan added the needs triage This issue needs to be triaged by the team label Jan 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage This issue needs to be triaged by the team
Projects
None yet
Development

No branches or pull requests

1 participant