Оптимізація продуктивності Angular: стратегії та найкращі практики

pic

Фото з: https://www.reddit.com/media?url=https%3A%2F%2Fpreview.redd.it%2F3splx63nx8c01.png%3Fwidth%3D1080%26crop%3Dsmart%26auto%3Dwebp%26s%3Dbbb5413d0fefc1697b1cd1e142301911dca24262

Оптимізація продуктивності Angular є важливим кроком для забезпечення швидких, ефективних і масштабованих додатків. Погана продуктивність може призвести до повільного завантаження, непотрібних повторних рендерів і високого використання пам'яті. У цій статті ми розглянемо основні стратегії, такі як оптимізація виявлення змін (change detection), lazy loading, tree shaking та SSR гідратацію. Ми також охопимо техніки зменшення розміру бандлів, покращення speed index і запобігання витокам пам'яті. Використовуючи ці найкращі практики, ви зможете підвищити чутливість додатку та забезпечити безшовний користувацький досвід. Давайте зануримося в основні оптимізації для високопродуктивного додатку на Angular!

Увімкнення AOT компіляції

Компіляція Ahead-of-Time (AOT) — це процес компіляції коду Angular під час етапу збірки, що зменшує обсяг роботи, яку браузер виконує під час виконання. Це призводить до швидшого рендерингу, менших бандлів і кращої безпеки.

За замовчуванням AOT увімкнено в Angular, коли ви запускаєте продукційну збірку за допомогою флагу --prod. Ось як ви можете його увімкнути:

Як увімкнути AOT:

Ви можете увімкнути AOT у вашому проекті Angular, просто використовуючи команду для продукційної збірки:

ng build --prod

Ця команда:

  • Увімкне AOT компіляцію.
  • Оптимізує ваш код, мінімізуючи його.
  • Виконає tree-shaking для видалення невикористаного коду.
  • Увімкне диференційне завантаження для сучасних та застарілих браузерів.

Перевірка, чи увімкнено AOT:

Ви можете явно перевірити, чи увімкнено AOT у вашому файлі angular.json, налаштувавши параметри продукційної збірки. Знайдіть файл angular.json і знайдіть налаштування для продукційної конфігурації. В розділі build переконайтеся, що параметр aot встановлений на true:

"configurations": {  
 "production": {  
 "aot": true,   
 "fileReplacements": [  
 {  
 "replace": "src/environments/environment.ts",  
 "with": "src/environments/environment.prod.ts"  
 }  
 ],  
 "optimization": true,  
 "buildOptimizer": true,  
 "sourceMap": false,  
 "extractCss": true,  
 "extractLicenses": true,  
 "namedChunks": false,  
 "vendorChunk": false  
 }  
}

Переваги AOT:

  1. Швидший рендеринг: Оскільки шаблони компілюються заздалегідь, браузер не має компілювати шаблони під час виконання, що призводить до швидшого рендерингу.
  2. Менші бандли: Компілятор Angular не включається до кінцевого JavaScript бандлу, що призводить до менших розмірів файлів.
  3. Раннє виявлення помилок: Помилки в шаблонах виявляються під час етапу збірки, що полегшує відлагодження.

Оптимізація виявлення змін

Виявлення змін (Change Detection) в Angular перевіряє стан додатку, щоб визначити, чи потрібно оновити вигляд. За замовчуванням Angular використовує ChangeDetectionStrategy.Default, що перевіряє кожен компонент щоразу, коли щось змінюється в додатку.
Це може бути неефективно для великих додатків, особливо коли багато компонентів не потребують частих оновлень.

Для оптимізації виявлення змін (Change Detection) можна переключитися на ChangeDetectionStrategy.OnPush, що вказує Angular перевіряти компонент тільки тоді, коли змінюються його вхідні властивості, або коли в цьому компоненті спрацьовують події.

Переваги використання ChangeDetectionStrategy.OnPush:

  • Зменшення циклів виявлення змін (Change Detection): Цикл виявлення змін буде ініційований тільки тоді, коли змінюються вхідні властивості компонента або коли спрацьовує подія (наприклад, клік по кнопці), що зменшує непотрібні перевірки.
  • Покращення продуктивності: Це зменшує кількість роботи, яку потрібно виконати Angular, що веде до швидшого рендерингу та кращої продуктивності.

Коли використовувати OnPush:

  • Компоненти з вхідними зв'язками (Input-bound Components): Коли компонент має прив'язки до вхідних даних (тобто отримує дані від батьківського компонента), OnPush працює добре, оскільки компонент потрібно оновлювати тільки тоді, коли ці вхідні дані змінюються.
  • Безстанні компоненти (Stateless Components): Компоненти, які не керують внутрішнім станом і залежні лише від вхідних даних, повинні використовувати OnPush, щоб уникнути непотрібних перевірок.
  • Додатки, чутливі до продуктивності (Performance-critical Apps): Для додатків з великою кількістю компонентів та частими оновленнями використання OnPush зменшує кількість циклів виявлення змін, що призводить до значних покращень продуктивності.

Як увімкнути OnPush:

Щоб увімкнути OnPush, просто додайте його до декоратора компонента.
Ось приклад того, як використовувати ChangeDetectionStrategy.OnPush:

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

@Component({  
 selector: 'app-your-component',  
 template: `
{{ message }}
`,    changeDetection: ChangeDetectionStrategy.OnPush   })   export class OnPushComponent {    message = 'Оптимізація продуктивності Angular';   } ```  

## Lazy Loading модулів

Lazy loading допомагає значно зменшити розмір вашого бандлу `main.js`, особливо коли йдеться про великі додатки на Angular. Відкладаючи завантаження певних частин вашого додатку (наприклад, фіч-модулів або компонентів) до того моменту, коли вони будуть потрібні, ви уникаєте збільшення розміру основного бандлу кодом, який не потрібен під час початкового завантаження. Це призводить до швидших часів запуску та кращої загальної продуктивності.  

Angular 14 представив **самостійні компоненти** (standalone components), які забезпечують більш модульний і гнучкий підхід до створення додатків Angular без потреби в Angular модулях (`NgModule`). Ви можете реалізувати lazy loading для самостійних компонентів так само, як для звичайних модулів.

## Як реалізувати Lazy Loading для самостійних компонентів:

Lazy loading самостійних компонентів працює схоже на lazy loading для модулів, але з спрощеним підходом, оскільки самостійні компоненти не потребують завантаження цілого модуля.

**Приклад самостійного компонента:**
Ось як може виглядати ваш самостійний компонент:

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

@Component({
selector: 'app-lazy-load',
template:
Lazy Loaded Standalone Component
,
standalone: true
})
export class LazyloadComponent {} ```

Налаштування Lazy Loading для самостійного компонента:
У вашій конфігурації маршрутизації (app-routes.ts) ви можете використовувати властивість loadComponent, щоб лінійно завантажити самостійний компонент:

import { Route } from '@angular/router';   
import { LazyloadComponent} from './lazyload/lazyload.component';      

export const appRoutes: Route[] = [    
  {    
    path: 'lazyload',    
    loadComponent: () => import('./lazyload/lazyload.component').then(m => m.LazyloadComponent)    
  },    
  { path: '', redirectTo: '/home', pathMatch: 'full' }   
]; ```  

У цій конфігурації властивість `loadComponent` гарантує, що компонент `LazyloadComponent` буде лінійно завантажено, коли користувач перейде на маршрут `/lazyload`. Цей підхід допомагає завантажити компонент лише тоді, коли це потрібно, оптимізуючи додаток.
Крім того, динамічний імпорт, `import('./lazyload/lazy.component')`, гарантує, що компонент завантажується на вимогу, що ще більше зменшує розмір основного бандлу.

## Tree Shaking

Процес tree-shaking в Angular призначений для видалення невикористаного коду з кінцевого бандлу, що допомагає зменшити розмір додатку. Однак ефективність tree-shaking залежить від того, як написаний код. Процес працює, аналізуючи код і визначаючи частини, які не використовуються або не є посиланими в додатку. Після завершення цього аналізу невикористаний код виключається з збірки, що забезпечує включення в кінцевий бандл лише необхідних частин коду.

Щоб повністю скористатися можливостями tree-shaking, важливо, щоб структура коду дозволяла бандлеру чітко визначити, які частини використовуються, а які — ні. Без належної структури коду бандлер може не виявити і не видалити всі непотрібні частини, що може призвести до збільшення розміру бандлу і вплинути на загальну продуктивність додатку.

Однак ви можете забезпечити, щоб ваш код був придатний для tree-shaking, дотримуючись таких практик:

- **Уникайте динамічних імпортів:** Динамічні імпорти (як `require` або `import()` всередині функцій) можуть не бути придатними для tree-shaking.
- **Використовуйте ES модулі:** Дотримуйтеся синтаксису **ES модулів** (`import`/`export`) для кращого tree-shaking.
- **Уникайте великих сторонніх бібліотек:** Великі бібліотеки, які не підтримують tree-shaking, можуть збільшити розмір бандлу. Використовуйте менші, модульні бібліотеки або імпортуйте тільки необхідні частини.

Наприклад, замість того, щоб імпортувати всю бібліотеку `lodash`, імпортуйте лише ті функції, які вам потрібні:

// Погано (Імпортується вся бібліотека)
import * as _ from 'lodash';

// Добре (Імпортується лише необхідна функція)
import { debounce } from 'lodash';
```

Webpack Bundle Analyzer

Використання Webpack Bundle Analyzer допомагає краще зрозуміти, які конкретно частини вашого додатку сприяють загальному розміру бандлу. Завдяки візуалізації вмісту вашого бандлу ви зможете визначити, які модулі, бібліотеки чи компоненти займають найбільше місця. Це дозволить зосередитись на оптимізації або видаленні великих залежностей для зменшення розміру бандлу.

Щоб розпочати, спершу потрібно встановити Webpack Bundle Analyzer як залежність для розробки за допомогою наступної команди:

npm install --save-dev webpack-bundle-analyzer

Далі, щоб проаналізувати продукційну збірку вашого додатку Angular, виконайте наступні команди:

ng build --prod --stats-json  
webpack-bundle-analyzer dist/stats.json

Команда ng build --prod --stats-json генерує продукційну збірку і виводить файл stats.json, що містить детальну інформацію про вашу збірку. Команда webpack-bundle-analyzer візуалізує цей файл, надаючи інтерактивне графічне зображення вашого бандлу.

Цей аналіз покаже вам розмір кожного модуля та залежності в вашому проекті, допомагаючи визначити потенційні області для оптимізації. Розуміння розподілу вашого бандлу дозволить приймати обґрунтовані рішення для покращення продуктивності вашого додатку.

Висновок

Оптимізація продуктивності вашого додатку Angular та зменшення розміру бандлу є ключовими для забезпечення швидкого, чуйного користувацького досвіду. Використовуючи стратегії, такі як AOT компіляція, Lazy Loading, Tree-shaking та Differential Loading, ви можете значно покращити часи завантаження. Додатково, мінімізуючи невикористаний код, сторонні бібліотеки та оптимізуючи зображення, можна ще більше зменшити розмір бандлу.

Застосування цих найкращих практик забезпечить високу продуктивність, масштабованість та ефективність вашого додатку, покращуючи досвід користувачів.
Продовжуйте оптимізувати та тестувати, щоб створювати швидші та надійніші Angular додатки!

Не забудьте поділитися цим та сміливо поставте лайк, якщо вам сподобалося! 👏👏👏

Ось посилання, які ви шукали:
https://angular.dev/tools/cli/aot-compiler
https://v17.angular.io/guide/change-detection
https://angular.dev/guide/routing/common-router-tasks#lazy-loading
https://blog.angulartraining.com/whats-tree-shaking-in-angular-da95c346114c
https://www.digitalocean.com/community/tutorials/angular-angular-webpack-bundle-analyzer

Перекладено з: Optimizing Angular Performance: Strategies & Best Practices

Leave a Reply

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