Angular Material: lazy loading Tabs content but only the first time it is accessed

Manuel Conde
2 min readJan 13, 2025

--

When working with Angular Material tabs, you might want to implement lazy loading for your tab content while ensuring the content persists once it’s loaded. By default, Angular Material detaches inactive tab content from the DOM, which can lead to unnecessary reloading every time you change the tab. Here’s how you can efficiently implement lazy loading with persistent tabs.

The Challenge

By default, <ng-template matTabContent> enables lazy loading for Angular Material tabs. However, once a tab is loaded, you might want the content to stay in memory to avoid reinitializing it when switching back. This is especially important for complex or stateful components. In my case, I use it to avoid reloading data (so avoid consuming API calls).

The Solution

Here’s my approach that ensures tabs are lazy-loaded initially but remain persistent after their first load:

In the component:

import { Component } from '@angular/core';

@Component({
selector: 'app-tabs-example',
templateUrl: './tabs-example.component.html',
styleUrls: ['./tabs-example.component.css']
})
export class TabsExampleComponent {
loadedTabs: boolean[] = [true, false, false];

onTabChange(index: number): void {
this.loadedTabs[index] = true;
}
}

Use a loadedTabs array in the component to track which tabs have been loaded. Also, update state with onTabChange()

In the template:

<mat-tab-group (selectedIndexChange)="onTabChange($event)">
<mat-tab>
@if (loadedTabs[0]) {
<app-tab1-content />
} @else {
<ng-template matTabContent>
<app-tab1-content />
</ng-template>
}
</mat-tab>

<mat-tab>
@if (loadedTabs[1]) {
<app-tab2-content />
} @else {
<ng-template matTabContent>
<app-tab2-content />
</ng-template>
}
</mat-tab>

<mat-tab>
@if (loadedTabs[2]) {
<app-tab3-content />
} @else {
<ng-template matTabContent>
<app-tab3-content />
</ng-template>
}
</mat-tab>
</mat-tab-group>

Explanation

Because the <ng-template matTabContent> directive ensures the content is only loaded when the tab is selected, we simply need yo use a single IF to decide when to use the directive or not.

After the content is loaded for the first time, it’s directly rendered instead of using the matTabContent template. This prevents Angular Material from detaching the DOM when switching tabs.

Advantages of This Approach

  • Improved Performance: Tabs are loaded only when needed, reducing the initial rendering time.
  • State Preservation: Once a tab’s content is loaded, it remains persistent, improving user experience for stateful components.

--

--

No responses yet