
If you’re building Angular apps in 2025, here are some practical, performance-oriented patterns you should definitely be using — from Signals and Change Detection to Storybook integration and template composition with ng-content
.
⚡ Signals for Reactive State Management
Signals are the go-to reactive primitive in Angular for change detection and improved performance.
Declaring a Signal
readonly totalSearchRelevantBrandCount = signal<number>(0);
Updating a Signal
Use .set()
to assign a new value:
this.totalSearchRelevantBrandCount.set(totalRelevantBrandCount);
Using a Signal in the Template
<h1>Total Brands: {{ totalSearchRelevantBrandCount() }}</h1>
🔄 Managing Observable Subscriptions
To avoid memory leaks, manage all subscriptions in one place using a Subscription
instance:
private readonly subs = new Subscription();
this.subs.add(
this.route.queryParamMap.subscribe(queryParams => {
this.isModal = !!queryParams.get('isModal');
})
);
this.subs.add(
this.route.paramMap.subscribe(params => {
console.log("Second subscription triggered");
})
);
Clean Up in ngOnDestroy
ngOnDestroy(): void {
this.subs.unsubscribe();
}
🧩 Using ng-content
for Template Composition
In your child component (app-panel-item
), use ng-content
to allow flexible content projection:
<div class="column-2">
<ng-content select="h5" />
<ng-content select="h6" />
<ng-content select="small" />
<ng-content select=".action-text" />
</div>
Parent Component Example
<app-panel-item><h4>Proposal History</h4></app-panel-item>
<app-panel-item><h4>Cover Page</h4></app-panel-item>
<app-panel-item><h4>About Us</h4></app-panel-item>
🧠 Change Detection: Always Use OnPush
For better performance, set your components to use ChangeDetectionStrategy.OnPush
.
@Component({
selector: 'app-panel-item',
templateUrl: './panel-item.component.html',
styleUrls: ['./panel-item.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
This ensures Angular only checks for changes when inputs change or a signal updates — not on every event.
📚 Component Isolation with Storybook
Storybook is a great tool to build, test, and visually isolate components.
Setup Example for PanelItemComponent
const meta: Meta<PanelItemComponent> = {
title: 'Shared Components/Panel Item',
component: PanelItemComponent,
decorators: [
moduleMetadata({
imports: [],
providers: [],
declarations: [PanelGroupComponent, SubtleLabelComponent],
}),
],
};
export default meta;
type Story = StoryFn<PanelItemComponent>;
Usage Story
export const Default: Story = () => ({
template: `
<app-panel-group>
<app-panel-item><h4>Living Room</h4><h5>$123</h5><h6>$234</h6></app-panel-item>
<app-panel-item><h4>Basement</h4><h6>$123</h6><small>2 items</small></app-panel-item>
</app-panel-group>
<app-panel-group>
<app-panel-item><h4>Proposal Total</h4><h5>$234</h5></app-panel-item>
</app-panel-group>
<app-panel-group class="gray">
<app-panel-item><h4>Proposal Total</h4><h5>$234</h5></app-panel-item>
</app-panel-group>
`,
});
Final Thoughts
In 2025, Angular is all about performance and maintainability. With signals, OnPush
strategy, clean subscription management, and smart use of ng-content
, you’re setting your app up for long-term success. Tools like Storybook only make the process of building robust, testable components even easier.
Let me know if you want a checklist version or a real-world sample project based on these practices!