Лучшие практики при разработке в Angular обеспечивают согласованность, читабельность кода, производительность, удобство обслуживания и масштабируемость.

Angular-разработка известна своей надежностью, масштабируемостью и производительностью, что делает ее популярной среди компаний по созданию сайтов и разработчиков. Следовательно, применение лучших практик в Angular-разработке приводит к согласованности, читабельности кода, производительности, удобству сопровождения и масштабируемости.

Это помогает членам команды работать вместе более эффективно, снижает вероятность появления ошибок и гарантирует, что кодовая база сможет поддерживать меняющиеся потребности. Цель этой статьи — перечислить лучшие практики, которым должны следовать разработчики Angular, чтобы обеспечить высокий уровень одобрения и успеха своих приложений.

Регулярное использование Angular CLI

Angular CLI — это очень мощный инструмент. Настоятельно рекомендуется его установить и применять как можно чаще. Использование предопределенных команд вместо того, чтобы делать все вручную, невероятно экономит время. Перечислим некоторые из самых распространенных 

  1. ng new — для создания приложения, готового к работе, прямо из коробки.

  2. ng generate — для генерации компонентов, маршрутов, сервисов и пайпов с помощью простой команды с тестовыми оболочками.

  3. ng serve — для локального тестирования приложения во время разработки.

  4. ng test — для запуска юнит или сквозных тестов.

  5. ng lint — для запуска наборов правил lint в коде.

Используйте функцию trackBy вместо ngFor

'ngFor' — это встроенная в Angular директива шаблона. Вместо отображения всего дерева DOM, вы можете использовать 'trackBy' вместо 'ngFor', что поможет вам предоставить уникальный и персонализированный идентификатор каждому элементу.

Используя 'ngFor', вы должны заново рендерить все дерево DOM после каждого изменения в массиве, в то время как при использовании 'trackBy' можно указать отдельные модификации, и Angular поможет вам внести изменения в DOM для указанного массива.

Используйте Async Pipes для экономии байтов памяти

Async Pipes — это встроенные атрибуты. Они позволяют сэкономить огромное количество байт памяти при создании крупномасштабного приложения, посещаемого тысячами пользователей. Они подписываются на наблюдаемые объекты (observables) и возвращают значение, которое было опущено.

Таким образом, они могут пригодиться при маркировке компонентов на выдаваемые значения и автоматической отписке от observables для ограничения ненужных утечек памяти.

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

Отсюда я перехожу к следующему пункту.

Предотвращение утечек памяти в Angular Observable

Утечки памяти Observable очень распространены и встречаются в каждом языке программирования, библиотеке или фреймворке. Angular не является исключением. Observables в Angular очень полезны, поскольку они оптимизируют данные, но утечка памяти — одна из очень серьезных проблем, которая может возникнуть, если вы не уделите ей должного внимания. Это может создать ужасную ситуацию в самом разгаре разработки. Вот несколько советов, которые помогут избежать утечек.

  1. Использование async pipe

  2. Использование take(1)

  3. Использование takeUntil()

Ленивая загрузка ваших модулей

Возможность ленивой загрузки в angular — позволяет модулю загружаться, когда вызывается маршрут. По умолчанию angular загружает все модули, что может увеличить время начальной загрузки страницы. Для ленивой загрузки модулей Angular используйте loadChildren (вместо component) в конфигурации маршрутов AppRoutingModule следующим образом. Обратите внимание, что все компоненты, сервисы, ассеты лениво загружаемых компонентов должны быть размещены в отдельной папке.

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

Следуйте принципу единственной ответственности

Компоненты — это строительные блоки, из которых состоит приложение. Согласно принципу SRP в контексте Angular, в каждом файле должен быть только один компонент. Технически, вы можете создать несколько классов вместе с компонентом в файле, но этого следует избегать. Это облегчает чтение, обслуживание и позволяет избежать скрытых ошибок. Стремитесь создавать компоненты небольшими и многократно используемыми. Это также позволяет избежать дублирования кода и соответствует принципу DRY (Don't Repeat Yourself. Не повторяйся).

Не сортируйте и не фильтруйте данные в пайпе (ориентировано на производительность)

Сортировка и фильтрация — дорогостоящие операции. Angular может вызывать Pipe много раз, следовательно, это может сильно снизить производительность. Мы должны отфильтровать или рассортировать модель данных в компоненте/сервисе, прежде чем привязывать ее к шаблону.

Создание повторно используемых компонентов и директив

Создание многократно используемых компонентов и директив в Angular может сэкономить время, усилия и средства в долгосрочной перспективе. Это помогает лучше организовать код, способствует согласованности, облегчает совместное использование кода и упрощает сопровождение. В результате улучшается эффективность разработки, общая организация, стандартизация дизайна и функциональности, а также масштабируемость приложения.

???? Совет: После создания многократно используемых компонентов Angular вы можете использовать инструментарий с открытым исходным кодом, такой как Bit, чтобы "собрать" их из любой кодовой базы и поделиться ими на bit.dev. Это позволит вашей команде повторно использовать и совместно работать над компонентами, чтобы писать масштабируемый код, ускорить разработку и поддерживать согласованный пользовательский интерфейс.

Оптимизация обнаружения изменений

  1. Используйте NgIf, а не CSS — если элементы DOM не видны, вместо того, чтобы скрывать их с помощью CSS, лучше удалить их из DOM с помощью *ngIf.

  2. Перенесите сложные вычисления в хук жизненного цикла (lifecycle hook) ngDoCheck, чтобы ускорить выполнение ваших выражений.

  3. Кэшируйте сложные вычисления как можно дольше.

  4. Используйте стратегию обнаружения изменений OnPush, чтобы сообщить Angular, что ничего не поменялось. Это позволит вам пропустить весь этап обнаружения изменений.

Однако данный механизм будет изменен или оттеснен на второй план более мощным подходом, называемым Angular Signals, начиная с V16. Если вы хотите узнать больше о том, как решается проблема обнаружения изменений, прочитайте статью об этом: How Angular Signals Solves an Age-Old Problem

Использование Smart — Dumb (Умных-Глупых) компонентов

Этот паттерн помогает использовать стратегию обнаружения изменений OnPush, чтобы сообщить Angular, что в dumb-компонентах ничего не поменялось.

Smart-компоненты используются для манипулирования данными, вызова API, уделения большего внимания функциональным возможностям и управлению состояниями. В то время как dumb-компоненты — это все, что касается косметики, они больше сосредоточены на том, как они выглядят.

Используйте index.ts

index.ts помогает нам сохранить все взаимосвязанные объекты вместе, так что нам не нужно беспокоиться об имени исходного файла. Это помогает уменьшить размер оператора импорта.

Например, у нас есть файл user/index.ts в виде

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

Мы можем все импортировать, используя имя исходной папки.

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

Заключение

Это лишь несколько практик, которые я могу выделить. Честно говоря, список довольно длинный, и он варьируется в зависимости от версии и требований проекта.


Приглашаем всех желающих на открытое занятие курса «Специализация Fullstack Developer», посвященное основам HTML. На занятии рассмотрим основы работы с HTML, начиная с самых простых вещей. Рассмотрим несколько типичных ошибок не только среди начинающих, но среди продолжающих и иногда даже сеньоров. Будем создавать разметку страницы авторизации: разберём основы семантики и атрибуты полей формы. Вебинар подойдёт как для начинающих, так и продолжающих обучение вёрстке.

Комментарии (4)


  1. s1im
    26.05.2023 10:34
    +1

    "Использование take(1)" - тут надо быть осторожным, это не замена unsubscribe. Если вы подпишитесь на Observable и передадите в .pipe(take(1)), то если он в ходе жизни вашего компонента не передаст ни одного значения, вы все еще останетесь на него подписанным, даже если компонент будет уничтожен. Надежнее использовать unsubscribe() или takeUntil().

    Ну и следите за обновлениями, начиная с Angular 16, можно использовать .pipe(takeUntilDestroyed());
    https://blog.angular.io/angular-v16-is-here-4d7a28ec680d


    1. s1im
      26.05.2023 10:34
      +1

      "Они позволяют сэкономить огромное количество байт памяти при создании крупномасштабного приложения, посещаемого тысячами пользователей." - странная фраза, огромное количество байт - это сколько? 100? 1000? 1000000 байт? И при чем тут крупномасштабность приложения и количество его пользователей, если, как правило, код выполняется на клиенте?

      "Async Pipes — это встроенные атрибуты." - что за встроенные атрибуты? Это обычный Angular Pipe, упрощающий работу с Observables.

      "Не сортируйте и не фильтруйте данные в пайпе" - в целом, зависит от примера использования, если массивы мелкие и changeDetection установлен в OnPush - то не так уж страшно.

      "Используйте NgIf, а не CSS" - может быть вредным советом, часто куда проще и производительнее скрыть какой-то компонент с помощью CSS, чем каждый раз создавать новый и позволять ему проходить новый lifecycle

      "Используйте index.ts" - к Angular-у совет отношение не имеет, это уже косметика на уровне TypeScript. Хотите пути еще короче - объявите их в config-e в разделе path https://www.typescriptlang.org/tsconfig#paths


      1. radtie
        26.05.2023 10:34

        Да там всё в таком же духе, правда эта претензия к оригиналу.

        >  trackBy вместо ngFor
        Не вместо, а вместе.

        И вообще причем здесь 2023, бОльшая часть тривиальных советов из официальной доки 2016 года + парочка мелких "лайфхаков".

        И кругом преждевременные оптимизации, типа использовать OnPush...хотя лучше бы указали на то, как легко накосячить в цепочки rxjs, после чего на каждый чих будут многократно дергаться серверные запросы или тяжелые калькуляции.


        1. s1im
          26.05.2023 10:34

          Да и в целом использование библиотеки RxJS не является обязательным условием для работы с данным фреймворком. Если оно по какой-то причине не устраивает или просто не нравится, то можно прекрасно обойтись без нее.