Наш черговий Tech Talk почався тоді, коли зима трошки відступила і це забезпечило не тільки дружню, а й теплу атмосферу. На початку наш технічний експерт Ігор Остапенко трошки розповів про наші внутрішні освітні івенти, об’єднані під брендом inTalks, такі як Tech Talk, KT Sessions, та, віднедавна, KT Local, що спочатку були ну дуже локальними – в рамках кімнати. Але з’явились ще бажаючі прийняти в них участь, чи то просто послухати, чи поділитись своїм досвідом, і тому ці локальні КТ сесії набули трішки іншого формату. Тепер вони проводяться приміщенні нашого офісу на Грушевського і приєднатись до них може будь-хто. Такі КТ сесії, на відміну від звичайних, не транслюються на всі наші офіси. Але це не тому, що нам шкода ділитись знаннями. Просто деякі теми набагато зручніше та доцільніше подавати в форматі дискусії, де кожний може задати питання або поділитись своїми думками та досвідом по темі. Але про це ми розповімо детальніше пізніше, а зараз про Tech Talk :).
Сьогоднішній Tech Talk був трішки незвичайним. Цього разу до нас приєднався найактивніший учасник нашого Meetup Олександр.
На мітапі він давав влучні пропозиції щодо вирішення завдань, поставлених перед нашим мікро-фреймворком). Також неможливо передати нашу радість та гордість від того, що два наші сьогоднішні спікери це цьогорічні випускники нашої інтернатури inCamp, Іван Литвиненко та Віталій Кобрін.
Так ось, Ігор розповів про наші внутрішні освітні програми та представив наших сьогоднішніх спікерів та теми їх презентацій, і… почалось! 🙂
AngularJS 1.x performance by Layer24 example
Перша презентація була присвячена дуже важливій темі – швидкодії у фронтенд додатках, побудованих на Angular, на прикладі нашого сервісу Layer24. Іван Литвиненко та Олександр Котов розповіли про свій досвід пошуку проблем з продуктивністю сервісу та їх вирішення. Їх дует був неперевершений :). Вони підтримували та доповнювали один одного. Вони розповіли про специфіку роботи фреймворка (мене тішить думка про те, що після нашого вчорашнього мітапу трішки більше людей розуміє значення цього слова 🙂 ) AngularJS та чому це приводило до проблем з продуктивністю. Треба додати, що це не значить, що AngularJS поганий або не підходить до нашої задачі. Це значить тільки те, що кожну технологію, мову програмування, фреймворк, бібліотеку та інше треба розуміти. Треба знати їх переваги та недоліки і використовувати перші та уникати других. Можливо, дехто подумає чому розробники одразу не зробили все “правильно”? І слово “правильно” тут недарма вказано в лапках. Бо “правильно” це дуже відносне поняття, особливо коли йдеться про продуктивність. Адже, оптимізувати доречно не все підряд, а саме те, що заважає користувачам у роботі з системою.
Презентація завершилась загальними порадами щодо використання AngularJS у додатках.
Іван Литвиненко: “В презентації ми з Олександром намагалися донести основи Angular 1.x, а потім показати ряд проблеми, з якими я зіткнувся, працюючи над проектом Layer24. При підготовці даної доповіді ми задавали собі питання: “Навіщо виділяти час і розповідати про цю дещо застарілу технологію, особливо з огляду виходу Angular 2?” Відповідь проста: legacy проекти. В першу чергу, ми розповіли концептуальні речі, те як фреймворк працює “під капотом”.
На початку презентації ми зосередились на реалізації two-way data binding, watchers і digest loop в AngularJS. Всі ці поняття ключові в контексті підвищення продуктивності роботи додатку.
Далі ми зосередилися на проблемах з продуктивністю на прикладі Layer24. Відображаючи велику кількість даних на певних сторінках ми помітили, що це призводить до їх повільної реакції на взаємодію з користувачем. На цих сторінках ми використовували наш власний універсальний компонент для виводу різного роду таблиць. Така універсальність, звичайно, має наслідки. Серед причин, які знижують продуктивність, ми виділили:
- велику кількість зайвих watchers;
- використання $eval expression;
- виведення кожної комірки з використанням вкладених ng-repeat (відбувається клонування scope).
Для того, щоб визначити наскільки кожна проблема є суттєвою, ми використовували звичайний Google Chrome profiler. Цей інструмент добре підходить для аналізу такого роду проблем.
Отже, для вирішення вище наведених проблем, було прийнято рішення про оптимізацію кількості watchers та вдосконалення способу генерації HTML для представлення таблиці.
Перше рішення про зменшення watchers вдалося вирішити, використавши Bindonce plugin. Так, нажаль довелося використовувати сторонню бібліотеку, бо в проекті використовується Angular 1.2.13. Починаючи з версії Angular 1.3 має вбудований синтаксис для виразів, що не будуть перевірятись в digest циклі, після їх стабілізації.
Наступне рішення було більш складне. Спочатку ми створили компонент, який будує шаблон рядка таблиці з конфігурації колонок, а потім за допомогою директиви $compile, будували DOM – елементи.
Результатом цих змін стало збільшення продуктивності більш ніж на 40% (ця цифра змінюється в залежності від сторінки і кількості даних).
Підбиваючи підсумки ми ще раз згадали загальні рішення, що покращують продуктивність AngularJS додатків:
- мінімізувати або уникати використання watchers, де можливо;
- уникати вкладених ng-repeat;
- використовувати одноразове зв’язування (Bindonce plugin або новий синтаксис виразів для AngularJS =>1.3.x);
- використовувати $watchCollection замість $watch з 3-м параметром;
- використовувати більш ефективні реалізації стандартних функцій в JavaScript.”
Angular 2 performance by Vault13 example
Наша друга пара доповідачів Віталій Кобрін та… Олександр Котов 🙂 занурили слухачів у захоплюючий світ другої версії популярного фреймворка для фронтенд додатків. І знову героєм доповіді став один з наших проектів – проект для нашого відділу TSD, що дозволяє вести облік обладнання та покликаний значно полегшити роботу наших адмінів. Де є вільні комп’ютери чи монітори, в кого зараз заховався Mac mini, чи як в один скан QR-коду дізнатися всі характеристики одного з PC в коморі – всі ці питання вирішує Vault13. Здавалося б, друга версія повинна бути набагато швидшою, але не все так просто. Звісно, розробники Angular врахували весь досвід використання першої версії фреймворку та переробили його настільки глибоко, що він став зовсім не схожим на перший. Проте, як ми вже всі знаємо, будь-яку технологію потрібно розуміти для того, щоб нею ефективно користуватись :).
Олександр з Віталієм скористались тим, що слухачі були вже розігріті, та почали з самого “м’яса”! Після крутої доповіді Івана та Олександра, публіка вже була морально підготовлена до більш глибшого занурення у світ Angular, а саме Angular 2.
Віталій Кобрін: “Знову ж таки з Олександром, ми почали розповідати про проблеми, з якими ми зіткнулися в ході розробки проекту Vault13 на основі Angular 2. Vault13 – система обліку обладнання для нашої команди TSD, розробка якої починалась в межах інтернатури inCamp, і зараз функціонує як повноцінний проект.
Одним із найскладніших компонентів Vault13 є динамічна таблиця, яка містить інформацію про всі пристрої компанії. Дана таблиця вміє фільтрувати та сортувати девайси за багатьма критеріями (тип, виробник, модель, власник, локація і т. д.). Застосовані фільтри впливають не лише на вміст таблиці, а й на набір колонок, що відображаються. Причому всі маніпуляції зі списком пристроїв відбуваються на клієнтській стороні.
Таким чином, дана таблиця не лише зручна, а й відносно повільна :(. Застосовуючи фільтри, користувач вимушений кожного разу терпляче очікувати на бажаний результат як мінімум 1-1,5 секунди. Вся проблема криється у внутрішній структурі фреймворку та неправильному використанні його можливостей.
Додаток на Angular 2 будується на основі компонентів. Компонентом може бути будь-який елемент сторінки, який відображає дані або дозволяє якось ними маніпулювати. Всі компоненти об’єднані між собою та утворюють деревоподібну структуру.
Для того, щоб відображати актуальні дані, Angular постійно реагує на будь-які події у додатку (будь-які дії користувача, відповідь від сервера …) та перевіряє чи не змінилися дані, зв’язані з компонентами, щоб оновити DOM-елементи у разі необхідності. Реалізацію такої поведінки забезпечує механізм ChangeDetection. Кожен компонент має власний Change Detector. Будь-яка подія, що може спричинити зміну моделі даних, провокує Angular на проходження по кожному компоненту та опитування їх Change Detector-ів, щоб дізнатися, чи раптом щось змінилось. А в разі виявлення змін – оновити DOM-елементи компонентів.
Angular 2 насправді дуже швидкий. За лічені мілісекунди він здатен обробляти сотні тисяч перевірок. Але зі збільшенням кількості компонентів на сторінці зростає і апетит фреймворку до ресурсів. Вгамувати його можна, зменшивши кількість непотрібних перевірок у кожен момент часу та звівши до мінімуму кількість операцій вставки та видалення DOM-елементів.
Приборкати Angular нам допоможуть такі рішення:
- Використання ChangeDetectionStrategy.OnPush
- Використання незмінних об’єктів (immutable objects)
- Використання observables
- NgZone.runOutsideAngular()
Поведінку Change Detector кожного компонента можна змінити, вказавши йому параметер ChangeDetectionStrategy.OnPush. За замовчуванням Change Detector робить повну перевірку на відповідність поточних даних компоненту з їх попередньою версією. Стратегія OnPush активує оновлення представлення компоненту тільки за умови заміни даних на інші (за іншим посиланням) або активації перевірки контролером одного з дочірніх компонентів.
Пошук змін у об’єктах моделі даних здійснюється шляхом перевірки всіх властивостей об’єктів. Використовуючи незмінні об’єкти та OnPush стратегію, можна скоротити час на перевірку, оскільки будуть перевірятися лише посилання до цих об’єктів у пам’яті.
Observables є реалізацією реактивного програмування. Використовуючи даний принцип, ми можемо визначити компоненти-слухачі та компоненти, які будуть прослуховуватися. Останні можуть генерувати події, а слухачі – ці події перехоплювати та реагувати на них. Це дозволяє нам контролювати процес здійснення перевірок Change Detector-ами або власноруч змінювати структуру DOM-елементів.
Генерування подій всередині NgZone.runOutsideAngular() сповіщає Angular про те, що йому не потрібно втручатися і обробляти ці події.
Застосування цих рішень дозволяє скоротити час на виконання скриптів до 40%. Звісно, цей показник залежить від даних та структури компонентів. Всі експерименти із застосування даних рішень проводились на тестовому стенді, тому жоден проект не постраждав.
Оптимізація Vault13 за такими принципами буде відбуватись трохи пізніше, але ми обов’язково сповістимо про результати.
Як підсумок хочеться додати, що наші зусилля не були даремними і нам все ж вдалося досягти непоганих результатів у оптимізації додатку на Angular 2. Але ми на цьому не зупинимось, є ще куди копати та що покращувати.”
Цього разу слухачі були дещо більш активними та задавали цікаві питання. Проте наших доповідачів це не спинило :). Продемонструвавши глибокі знання теми, вони швидко відповідали на складні питання та продовжували свою презентацію. Навіть влучні коментарі та доречні запитання одного з представника користувачів Vault13, Павла Хавроненко, не змогли їх зупинити :).
Під час презентації нам привезли підкріплення у вигляді піци і дехто не гаяв часу! 😉
І знову у кінці презентації наші колеги поділилися загальними рекомендаціями щодо використання вже другої версії Angular у фронтенд додатках.
“Чорне віконце” у світ терміналів
Останньою за розкладом, проте не за важливістю була презентація Ігоря Остапенка про історію терміналів. Усі програмісти працюють з терміналами і розуміння їх історії допомагає робити це більш осмислено. Ігор, як завжди, зумів розповісти про цю тему цікаво та невимушено.
Вкотре Ігор показав важливість не просто використовувати робочі інструменти, а ще й розуміти історію їх виникнення та еволюції. Чому це важливо? Тому що багато речей в сфері ІТ тягнуться ще з “доісторичних” часів, коли комп’ютерів ще не було, а для друку тексту використовувались тільки друкарські машини. Так, саме друкарська машинка була пращуркою сучасних терміналів.
Ігор Остапенко: “Ну, прям уж так, чтобы знать историю, – это сегодня необязательно. Но, в некоторых вещах, история – это как концептуальная документация, которая позволяет разложить все по своим полочкам, увидеть все слои абстракции и понять, кто за что отвечает в цепочке событий. Вот и с нашим stdout похожая история, мы в него выдаем последовательность, а потом, к примеру, вывод в терминале расходится с нашим ожиданием. Непонятно кто виноват и куда копать, а оказывается многое может зависеть от конкретной ситуации в runtime.
С другой стороны, пример с newline format показывает, что историю знать не обязательно, важно понимать проблему, способы ее решения и не забывать о ней. А история, стоящая за этим вопросом, возможно, позволит создать больше ассоциаций в голове, чтобы лучше проникнуться темой и действительно не забывать о таких вещах.
А вот история, которая приводит нас к таким вещам как GNU Readline, очень важна, ибо, как считаю лично я, она лучше всего раскрывает суть и концепты. Почему так? Да потому, что терминалы и способы взаимодействия с программами в unix like системах основаны на старушке TTY-абстракции, которая пережила различные эпохи программного обеспечения и устройств ввода-вывода, что привело к различным наслоениям в API, и к свалке backward compatibility, с чем приходится иметь дело и по сей день. В связи с чем через историю легче могут даться такие темы, как: process sessions & groups, signals, job control, line disciplines, etc.
А на самом деле, мораль еще проще – путь развития профессионала предполагает разбираться в том, что мы делаем и используем, понимать суть происходящего и как можно точнее понимать протекающие процессы внутри.”
Олександр Котов: “Я дуже вдячний хлопцям, за старанно підготовлені презентації та впевнені виступи. Ще вчора хлопці отримували свій перший досвід в нашій компанії, і от вони вже читають власні доповіді з непростих тем. Мені завжди подобалось ділитися своїм досвідом та допомогати розбиратися з різними питаннями. Та ще приємніше було бачити, як випускники минулих сезонів інтернатури вже діляться своїм досвідом з нашою поточною групою то іншими співробітниками компанії.
Вам може здаватися, що у вас не достатньо досвіду або відома вам інформація вже нікому не цікава. Але слухачі є там, де є розмова. Не бійтеся ділитися своїм досвідом, яким би специфічним чи невеликим він не був, і ви знайдете своїх співрозмовників та слухачів. Knowlеdge sharing – це цруто! :)”
Post A Reply