Мій список помилок в Angular, яких повинні уникати розробники
Вітаю! Мене звати Олексій Куракін, я працюю в компанії Zazmic Angular/Node розробником вже 2 роки. Я почав програмування на Angular ще у коледжі, спочатку просто «грався», а потім на ньому ще й диплом написав.
Хотів би поділитися досвідом роботи з цим фреймворком, а точніше, — порадами, як не треба працювати з ним і яких помилок уникати під час написання коду на Angular. Сподіваюся, що ця стаття буде корисна програмістам-початківцям.
Я зібрав п’ять, на мою думку, найкритичніших моментів. Буду вдячний, якщо доповните у коментарях своїми прикладами.
1. Логіка, що дублюється
Розглянемо приклад: тобі як програмісту дали задачу написати програму, яка описує різних супергероїв та наділяє їх тими чи іншими суперздібностями. Ти починаєш їх описувати в компонентах (наприклад, ‘supermanComponent’, ‘homelanderComponent’) і розумієш, що у Супермена та у Хоумлендера є однакова здібність — «стріляти лазером з очей».
І замість того, щоб писати у кожному компоненті функцію shootLaserFromEyes(), ти можеш винести її у сервіс SuperHeroPowers(), якій буде викликатися у компонентах Супермена та Хоумлендера.
2. Відписуватися від Observables
Часто, коли пишеться якийсь асинхронний код, ми просто створюємо потік, підписуємося на нього та продовжуємо працювати далі. Але так не можна робити, тому що потік не закриється сам собою, і продовжуватиме створювати навантажування на комп’ютер на стороні клієнта.
Особливо критично, якщо це не якийсь потужний процесор, то є велика ймовірність, що через певний час перебування на сайті комп’ютер користувача почне гальмувати, і користувач буде засмучений.
Тому варто не забувати: «якщо підписався на потік — то треба і відписатися від потоку». Для цього є кілька способів:
- найочевидніший — це Unsubscribe. Просто відписатися від потоку при деструктуризації компонента;
- інший варіант — Rxjs оператор take(), у якому можна вказати, скільки разів ми хочемо отримати дані з потоку. Наприклад, якщо написати take(1), то наш потік стане звичайним промісом;
- також можна скористатися Async Pipe, якщо ми хочемо передати якусь асинхронну дату в якийсь дочірній елемент. Ця функція бере потік і повертає останнє значення, яке передавалося, а після деструктуризації компонента автоматично відписується від підписки.
3. Витік пам’яті
Те ж саме, що і у другому пункті, але може відбуватися не тільки через не закриті потоки. З назви зрозуміло, що проблема виникає, коли є витік пам’яті. Це коли програма неправильно керує пам’яттю, що виділена, і пам’ять починає «витікати», тобто збільшується навантаження на процесор.
Це може відбуватися через незакритий потік в компоненті, який перерендерується, наприклад, кожної секунди. Очевидно, що вже через кілька хвилин він створить таку кількість потоків, що це заб’є нам усю пам’ять. Тому не забувайте використовувати unsubscribe.
Наступною причиною витікання пам’яті може бути не оптимізований код, наприклад, якісь монструозні цикли в циклі в циклі, які після кожної зміни в компоненті спрацьовують та перераховують усю дату в масиві з тисячею елементів. Намагайтеся писати компактний та зрозумілий код, щоб потім не доводилося розплачуватися пам’яттю.
Також, щоб уникнути цієї проблеми рекомендую використовувати Lazy Loading. Він дає можливість завантажувати модулі поступово, тобто коли користувач буде працювати з тим чи іншим функціоналом, то будуть завантажуватися саме ті модулі, що йому відповідають.
Й останнє, але не за своїм значенням, — це керування станом застосунку. Як найяскравіший приклад наведу NgRx — це фреймворк для створення реактивних додатків. Мається на увазі, що стан додатка зберігається в одному місці, завдяки чому програміст може з будь-якого місця у програмі звернутися (або підписатися) на зміну цього стану. Це набагато спрощує розробку внаслідок того, що спрощується контакт між компонентами.
Наприклад: є Бетмен і є Супермен, і вони вирішили «підписатися» на подію, коли хтось буде грабувати банк. Виходить, що коли значення перемінної isBankRobberyActive буде true, вони одночасно отримують зміни і зможуть одночасно вилетіти на місце злочину та з притаманною їм легкістю перемогти злочинців.
4. Написати такий код, що не читається
Цей пункт більше стосується коду в цілому, ніж Angular, але я хотів би попередити усіх новачків про це. Код не обов’язково повинен займати мінімальну кількість рядків.
Тобто якщо ви напишете щось типу такого коду array.map(i => ++i).filter(j => j).reduce(k => k, 0) в один рядок, то це справді круто, але розробник, якому через кілька місяців доведеться дивитися на цей код, точно не подякує вам.
Краще написати трохи більше рядків коду, але зробити його зрозумілішим для інших колег, ніж вмістити все в один рядок і сподіватися, що ти запам’ятаєш, що тут відбувається з нашим бідним масивом.
Коли я тільки почав працювати, я написав тернарний оператор в тернарному операторі, і ще в тернарному операторі, і так далі, в одному з темплейтів. Потім, коли через декілька місяців мені самому знадобилося щось додати в цей код — я витратив близько 20 хвилин тільки щоб зрозуміти, а що ж тут взагалі відбувається :)
5. Намагатися уникати реактивних форм
Так, спочатку вони можуть здатися незрозумілими і навіть страшними, але вивчити їх варто!
Реактивні форми надають розробнику зручну можливість валідації полів (ви навіть можете написати кастомний валідатор, вау!), дозволяють відстежувати їх стан і взагалі всяку роботу з полями.
Коли я написав форму для створення тригерів, де кожне поле повинно змінюватися і додаватися динамічно у застосунку, я був дуже вдячний тим людям, які колись придумали ці реактивні форми. Тому що без них я взагалі не впевнений, що зміг би написати щось, що працює.
Це усе, чим я хотів би поділитися з вами. Дякую за увагу та сподіваюся, що це було корисним. Чекаю на ваші коментарі!
12 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів