Best practices for 2023

Angular development best practices ensure consistency, code readability, performance, maintainability, and scalability.

Angular development is known for its reliability, scalability, and performance, making it popular with website builders and developers. Therefore, applying best practices in Angular development leads to consistency, code readability, performance, maintainability, and scalability.

This helps team members work together more effectively, reduces the chance of bugs, and ensures that the codebase can support changing needs. The purpose of this article is to list the best practices that Angular developers should follow in order to ensure a high level of approval and success for their applications.

Regular use of Angular CLI

Angular CLI is a very powerful tool. It is strongly recommended to install it and use it as often as possible. Using predefined commands instead of doing everything manually is incredible saves time. We list some of the most common

  1. ng new – to create a ready-to-go application right out of the box.

  2. ng generate – to generate components, routes, services and pipes with a simple command with test shells.

  3. ng serve – for testing the application locally during development.

  4. ng test – to run unit or end-to-end tests.

  5. ng lint – to run lint rule sets in code.

Use the trackBy function instead of ngFor

‘ngFor’ is a built-in template directive in Angular. Instead of displaying the entire DOM tree, you can use ‘trackBy’ instead of ‘ngFor’ to help you provide a unique and personalized ID for each element.

Using ‘ngFor’ you have to re-render the entire DOM tree after each change to the array, while using ‘trackBy’ you can specify individual modifications and Angular will help you make changes to the DOM for the specified array.

Use Async Pipes to Save Bytes of Memory

Async Pipes are built-in attributes. They allow you to save a huge amount of memory bytes when creating a large-scale application visited by thousands of users. They subscribe to observables and return the value that was omitted.

Thus, they can come in handy when marking components with emitted values ​​and automatically unsubscribing from observables to limit unnecessary memory leaks.

selector: 'async-observable-pipe',
template: '
observable|async: Time: {{ time | async }}
' }) 
export class AsyncObservablePipeComponent 
  time = new Observable((observer: Observer) => {     
    setInterval(() => Date().toString()), 1000); 

From here I move on to the next point.

Preventing memory leaks in Angular Observable

Observable memory leaks are very common and occur in every programming language, library or framework. Angular is no exception. Observables in Angular are very useful as they optimize data, but memory leak is one of the very serious problems that can occur if you don’t pay attention to it. This can create a dire situation in the middle of development. Here are some tips to help you avoid leaks.

  1. Using an async pipe

  2. Using take(1)

  3. Using takeUntil()

Lazy loading your modules

Lazy loading capability in angular – Allows a module to be loaded when a route is called. By default, angular loads all modules, which can increase the initial page load time. To lazy load Angular modules, use loadChildren (instead of component) in the AppRoutingModule routes configuration as follows. Please note that all components, services, assets of lazily loaded components must be placed in a separate folder.

const routes: Routes = [
    path: 'items',
    loadChildren: () => import('./users/users.mdule')
      .then(m => m.UsersModule)

Follow the Single Responsibility Principle

Components are the building blocks that make up an application. According to the SRP principle in the context of Angular, Each file must have only one component.. Technically, you can create multiple classes along with a component in a file, but this should be avoided. This makes it easier to read, maintain, and avoid hidden bugs. Strive to keep components small and reusable. It also avoids code duplication and is DRY (Don’t Repeat Yourself).

Do not sort or filter data in the pipe (performance oriented)

Sorting and filtering are expensive operations. Angular can call Pipe many times, hence it can severely degrade performance. We must filter or sort the data model in the component/service before binding it to the template.

Creating Reusable Components and Directives

Creating reusable components and directives in Angular can save you time, effort, and money in the long run. This helps organize code better, promotes consistency, makes code easier to share, and easier to maintain. The result is improved development efficiency, overall organization, standardization of design and functionality, and application scalability.

💡 Tip: After creating reusable Angular components, you can use an open source toolkit such as Bitto “collect” them from any codebase and share them on This will allow your team to reuse and collaborate on components to write scalable code, accelerate development, and maintain a consistent user experience.

Change detection optimization

  1. Use NgIf, not CSS – if DOM elements are not visible, instead of hiding them with CSS, it’s better to remove them from the DOM with *ngIf.

  2. Move complex calculations to the ngDoCheck lifecycle hook to speed up your expressions.

  3. Cache complex calculations for as long as possible

  4. Use the OnPush change detection strategy to tell Angular that nothing has changed. This will allow you to skip the entire change detection step.

However, this mechanism will be changed or sidelined by a more powerful approach called Angular Signals starting in V16. If you want to know more about how the change detection problem is solved, read the article about it: How Angular Signals Solves an Age-Old Problem

Using Smart – Dumb (Smart-Dumb) Components

This pattern helps to use the OnPush change detection strategy to tell Angular that nothing has changed in dumb components.

Smart Components are used to manipulate data, call APIs, focus more on functionality, and manage states. While dumb components are all about cosmetics, they are more focused on how they look.

Use index.ts

index.ts helps us keep all related objects together so that we don’t have to worry about the source file name. This helps to reduce the size of the import statement.

For example, we have a file user/index.ts as

export * from './user-auth';
export * from './user-config';
export { PaymentComponent }from './user-payment.component';

We can import everything using the source folder name.

import {User, UserConfig } from '..user';


These are just a few practices that I can highlight. To be honest, the list is quite long and it varies depending on the version and project requirements.

We invite everyone to open class course “Fullstack Developer Specialization”, dedicated to the basics of HTML. In the lesson, we will cover the basics of working with HTML, starting with the simplest things. Let’s consider a few typical mistakes not only among beginners, but among continuing and sometimes even seniors. We will create the markup of the authorization page: we will analyze the basic semantics and attributes of the form fields. The webinar is suitable for both beginners and those who continue learning layout.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *