Please use this identifier to cite or link to this item:
https://er.chdtu.edu.ua/handle/ChSTU/7093| Title: | Оптимізація продуктивності програм в Single Page Applications |
| Authors: | Немченко, Вадим В'ячеславович Андрющенко, Данило Андрійович |
| Keywords: | оптимізація продуктивності;Single Page Applications;Angular;Change Detection;Lazy Loading;Web Workers;продуктивність;PERFORMANCE;OPTIMIZATION;SINGLE PAGE APPLICATIONS;ANGULAR;CHANGE DETECTION;LAZY LOADING;WEB WORKERS |
| Issue Date: | 16-Dec-2025 |
| Abstract: | АНОТАЦІЯ
Андрющенко Данило Андрійович, студент спеціальності 121 «Інженерія програмного забезпечення». Представлено кваліфікаційну роботу магістра на тему – «Оптимізація продуктивності програм в Single Page Applications» у Черкаському державному технологічному університеті у місті Черкаси у 2025 році.
Кваліфікаційна робота магістра присвячена дослідженню методів підвищення продуктивності програмного забезпечення із використанням TypeScript, Angular, RxJS. У роботі проаналізовано сучасні технології та підходи до оптимізації SPA, розроблено архітектуру системи та функціональні модулі, а також виконано тестування розробленого програмного забезпечення. Результатом дослідження є реалізація демонстраційного SPA-додатку, що підтверджує ефективність застосованих методів оптимізації та відповідає сучасним вимогам продуктивності, масштабованості та зручності використання. Розроблене програмне забезпечення впроваджено у тестове середовище, що демонструє його готовність до практичного застосування. ANNOTATION Andriushchenko Danylo, a student of the 121 "Software Engineering" specialty, presents a master's qualification work on the topic “Performance Optimization of application performance in Single Page Applications” at Cherkasy State Technological University in Cherkasy in 2025. The master’s thesis is dedicated to researching methods for improving the performance of software using TypeScript, Angular, and RxJS. The work analyzes modern technologies and approaches to optimizing Single Page Applications (SPA), develops the system architecture and functional modules, and performs testing of the implemented software. The result of the research is the development of a demonstration SPA application that confirms the effectiveness of the applied optimization methods and meets modern requirements for performance, scalability, and usability. The implemented software has been deployed in a test environment, demonstrating its readiness for practical use. |
| URI: | https://er.chdtu.edu.ua/handle/ChSTU/7093 |
| Appears in Collections: | 121 Інженерія програмного забезпечення (Інженерія програмного забезпечення) |
Files in This Item:
| File | Description | Size | Format | |
|---|---|---|---|---|
| Кваліфікаційна робота магістра Андрющенко Данила Андрійовича.pdf Restricted Access | 6.44 MB | Adobe PDF | View/Open Request a copy |
Items in DSpace are protected by copyright, with all rights reserved, unless otherwise indicated.
Extracted text
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
ЧЕРКАСЬКИЙ ДЕРЖАВНИЙ ТЕХНОЛОГІЧНИЙ УНІВЕРСИТЕТ
Факультет інформаційних технологій і систем
Кафедра програмного забезпечення автоматизованих систем
ПОЯСНЮВАЛЬНА ЗАПИСКА
до кваліфікаційної роботи
«магістра»
освітній рівень
на тему: Оптимізація продуктивності програм в Single Page Applications
Магістранта Андрющенко Д. А.
(прізвище та ініціали)
Керівник Немченко В. В.
(прізвище та ініціали)
Рецензент Левченко С. П.
(прізвище та ініціали)
Черкаси 2025
Черкаський державний технологічний університет
повне найменування вищого навчального закладу
Факультет інформаційних технологій і систем
Кафедра програмного забезпечення автоматизованих систем
Освітній рівень магістр
Спеціальність 121 «Інженерія програмного забезпечення»
Освітня програма Інженерія програмного забезпечення
ЗАТВЕРДЖУЮ
Зав. кафедри ПЗАС, професор
С. Голуб
«___» _______________ 2025 року
З А В Д А Н Н Я
НА КВАЛІФІКАЦІЙНУ РОБОТУ СТУДЕНТУ
Андрющенко Данило Андрійович
(прізвище, ім’я, по батькові)
1. Тему проекту (роботи) Оптимізація продуктивності програм в Single Page Applications
Керівник проекту (роботи) Немченко Вадим В'ячеславович к.т.н. доцент
(прізвище, ім’я , по батькові, науковий ступінь, вчене звання)
Затверджені наказом Черкаського державного технологічного університету від «07 жовтня»
2025 року № 307/03-03
2.Строк подання студентом проекту (роботи) 09.12.2025
3. Вхідні дані до проекту (роботи) 1) Платформа x86-64, 2) Мова програмування TypeScript
4. Зміст розрахунково-пояснювальної записки (перелік питань, які потрібно розробити)
Розділ 1. Існуючі методи та засоби розв’язання поставлених завдань
Розділ 2. Теоретичні та експериментальні дослідження
Розділ 3. Впровадження результатів дослідження у практику проектування програмного
забезпечення інформаційних систем
Розділ 4. Розробка та тестування програмного забезпечення
Висновки;
Список використаних джерел;
Додатки А, Додатки Б, Додатки В.
5. Перелік графічного матеріалу (з точним зазначенням обов’язкових робіт проекту);
Додатки Г - Графічний матеріал.
6. Консультанти розділів роботи
Прізвище, ініціали та посади Підпис, дата
Розділ
консультанта Завдання видав Завдання прийняв
1
2
3
4
7. Дата видачі завдання вересень 2025 р.
КАЛЕНДАРНИЙ ПЛАН
Строк виконання
№
Назва етапів випускної роботи етапів кваліфікаційної Примітки
п/п
роботи
1 Постановка задачі 09.09.2025 виконано
2 Підготовка завдання 12.09.2025 виконано
3 Погодження завдання 18.09.2025 виконано
4 Затвердження завдання 27.09.2025 виконано
Основна стадія
1 Підбір матеріалів 30.09.2025 виконано
2 Аналіз шляхів вирішення поставленої задачі 03.10.2025 виконано
3 Розрахунок основних параметрів роботи 08.10.2025 виконано
4 Вибір кінцевого варіанту проектного рішення 17.10.2025 виконано
5 Оформлення первісної редакції роботи 23.10.2025 виконано
Заключна стадія
1 Узгодження прийнятих проектних рішень з 08.11.2025 виконано
керівником
2 Оформлення пояснювальної записки роботи в 28.11.2025 виконано
кінцевій редакції
3 Попередній захист роботи 05.12.2025 виконано
4 Затвердження роботи 06.12.2025 виконано
5 Рецензування роботи 09.12.2025 виконано
6 Захист роботи 12.12.2025
Студент ___________ Андрющенко Д.А.
(підпис) (прізвище та ініціали)
Керівник роботи ______________ Немченко В.В.
(підпис) (прізвище та ініціали)
АНОТАЦІЯ
Андрющенко Данило Андрійович, студент спеціальності 121 «Інженерія
програмного забезпечення». Представлено кваліфікаційну роботу магістра на
тему – «Оптимізація продуктивності програм в Single Page Applications» у
Черкаському державному технологічному університеті у місті Черкаси у 2025
році.
Кваліфікаційна робота магістра присвячена дослідженню методів
підвищення продуктивності програмного забезпечення із використанням
TypeScript, Angular, RxJS. У роботі проаналізовано сучасні технології та
підходи до оптимізації SPA, розроблено архітектуру системи та функціональні
модулі, а також виконано тестування розробленого програмного забезпечення.
Результатом дослідження є реалізація демонстраційного SPA-додатку, що
підтверджує ефективність застосованих методів оптимізації та відповідає
сучасним вимогам продуктивності, масштабованості та зручності
використання. Розроблене програмне забезпечення впроваджено у тестове
середовище, що демонструє його готовність до практичного застосування.
Ключові слова: оптимізація продуктивності, Single Page Applications,
Angular, Change Detection, Lazy Loading, Web Workers, продуктивність.
ANNOTATION
Andriushchenko Danylo, a student of the 121 "Software Engineering"
specialty, presents a master's qualification work on the topic “Performance
Optimization of application performance in Single Page Applications” at Cherkasy
State Technological University in Cherkasy in 2025.
The master’s thesis is dedicated to researching methods for improving the
performance of software using TypeScript, Angular, and RxJS. The work analyzes
modern technologies and approaches to optimizing Single Page Applications (SPA),
develops the system architecture and functional modules, and performs testing of the
implemented software. The result of the research is the development of a
demonstration SPA application that confirms the effectiveness of the applied
optimization methods and meets modern requirements for performance, scalability,
and usability. The implemented software has been deployed in a test environment,
demonstrating its readiness for practical use.
Keywords: PERFORMANCE OPTIMIZATION, SINGLE PAGE
APPLICATIONS, ANGULAR, CHANGE DETECTION, LAZY LOADING, WEB
WORKERS, PERFORMANCE.
ЗМІСТ
ПЕРЕЛІК УМОВНИХ СКОРОЧЕНЬ ............................................................................ 6
ВСТУП .............................................................................................................................. 7
РОЗДІЛ 1. ІСНУЮЧІ МЕТОДИ ТА ЗАСОБИ РОЗВ’ЯЗАННЯ ПОСТАВЛЕНИХ
ЗАВДАНЬ ....................................................................................................................... 10
1.1 Конкретизація завдань роботи .......................................................................... 10
1.2 Актуальні проблеми, що виникають в процесі виконання завдань .............. 15
1.3 Методи та засоби, які вже використовуються для усунення проблем та
виконання завдань .................................................................................................... 18
РОЗДІЛ 2. ТЕОРЕТИЧНІ ТА ЕКСПЕРИМЕНТАЛЬНІ ДОСЛІДЖЕННЯ ............. 22
2.1 Теоретичні дослідження .................................................................................... 22
2.2 Експериментальні дослідження ........................................................................ 33
РОЗДІЛ 3. ВПРОВАДЖЕННЯ РЕЗУЛЬТАТІВ ДОСЛІДЖЕНЬ У ПРАКТИКУ
ПРОЄКТУВАННЯ ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ ІНФОРМАЦІЙНИХ
СИСТЕМ ........................................................................................................................ 46
3.1 Моделювання предметної області .................................................................... 46
3.1.1 Предметна область моделювання. Модель предметної області.
Словник предметної області .............................................................................. 46
3.1.2 Елементи моделювання предметної області ........................................... 48
3.1.3 Робоча область моделювання ................................................................... 50
3.2 Формування та аналіз вимог ............................................................................. 52
3.2.1 Формування вимог до програмного забезпечення. Первинні і детальні
вимоги. Вимоги замовника і розробника. Функціональні та нефункціональні
вимоги .................................................................................................................. 52
3.2.2 Формування вимог за допомогою діаграми прецедентів ...................... 55
3.2.3 Проектування логічної структури програмного комплексу .................. 57
3.2.3.1 Діаграми класів .................................................................................. 57
3.2.3.2 Діаграма пакетів ................................................................................. 60
3.2.4 Архітектурне проектування ...................................................................... 61
3.2.4.1 Діаграма компонентів ........................................................................ 61
3.2.4.2 Розгортання програмної системи на апаратних засобах. Діаграма
розгортання ..................................................................................................... 62
3.2.5 Моделювання поведінки системи ............................................................ 63
3.2.5.1 Діаграма діяльності ........................................................................... 63
3.2.5.2 Діаграма послідовності ..................................................................... 65
3.2.5.3 Діаграма комунікації ......................................................................... 67
3.2.5.4 Діаграма скінченного автомату ........................................................ 68
РОЗДІЛ 4. РОЗРОБКА ТА ТЕСТУВАННЯ ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ . 72
4.1 Розробка програмного комплексу .................................................................... 72
4.1.1 Обґрунтування вибору засобів реалізації ................................................ 72
4.1.2 Опис структурної (функціональної) схеми ............................................. 74
4.1.3 Опис логічної схеми системи ................................................................... 77
4.1.4 Розробка бази даних .................................................................................. 78
4.1.5 Розробка інтерфейсу користувача ............................................................ 78
4.1.6 Опис розробки програмних компонентів ................................................ 82
4.2 Тестування системи ........................................................................................... 83
4.2.1 Модульне тестування ................................................................................ 83
4.2.2 Інтеграційне тестування ............................................................................ 86
4.2.3 Системне тестування ................................................................................. 87
4.2.4 Приймальне тестування ............................................................................ 89
4.3 Приклади впровадженого програмного комплексу........................................ 91
ВИСНОВКИ ................................................................................................................... 95
СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ ..................................................................... 98
ЧДТУ 252471.001 ПЗ
ПЕРЕЛІК УМОВНИХ СКОРОЧЕНЬ
SPA – Single Page Application (односторінковий застосунок)
API – Application Programming Interface (Інтерфейс програмування
застосунків)
UI – User Interface (Інтерфейс користувача)
UX – User Experience (Досвід користувача)
TTI – Time to Interactive (Час до взаємодії)
FCP – First Contentful Paint (Час до першого відображення)
SI – Speed Index (Індекс швидкості)
6
ЧДТУ 252471.001 ПЗ
ВСТУП
Актуальність теми. У сучасному веб-просторі Single Page Applications
(SPA) стали домінуючим підходом до розробки інтерфейсів користувача завдяки
своїй здатності забезпечувати високу інтерактивність, плавний користувацький
досвід та миттєві реакції на дії користувача без перезавантаження сторінки.
Розробка таких застосунків належить до сфери інженерії програмного
забезпечення, яка зосереджується на створенні масштабованих, ефективних та
надійних інформаційних систем. Проте разом із зростанням функціональності та
складності SPA-додатків постає низка викликів, пов’язаних із продуктивністю,
зокрема: збільшення часу початкового завантаження, високий рівень споживання
ресурсів, повільна реакція інтерфейсу та надмірне навантаження на браузер.
У контексті сучасних інженерних підходів особливу увагу привертає
технологічний стек, що використовується у розробці SPA, зокрема Angular,
TypeScript, RxJS та інструменти веб-оптимізації. З огляду на стрімкий розвиток
фронтенд-технологій, підвищені вимоги до продуктивності та поширення
мобільних платформ, де обмеженість ресурсів особливо відчутна, тема
дослідження є надзвичайно актуальною.
Отже, дослідження методів підвищення продуктивності SPA-додатків є
важливим кроком на шляху до створення ефективних, швидких та надійних веб-
застосунків, які відповідають сучасним стандартам якості та очікуванням
користувачів.
Зв’язок з науковими програмами, планами, темами. Робота виконується
в рамках наукових досліджень кафедри програмного забезпечення
автоматизованих систем.
Мета і завдання досліджень. Підвищення продуктивності SPA шляхом
впровадження сучасних методів оптимізації, спрямованих на зменшення часу
завантаження, скорочення споживання ресурсів та прискорення рендерингу
компонентів інтерфейсу.
Для досягнення поставленої мети необхідно вирішити такі завдання:
7
ЧДТУ 252471.001 ПЗ
﹣ проаналізувати сучасні тенденції та підходи до розробки SPA-додатків з
точки зору продуктивності;
﹣ класифікувати основні чинники, що впливають на продуктивність SPA,
на прикладі популярних фреймворків (Angular, React);
﹣ визначити та систематизувати методи оптимізації, які застосовуються на
різних етапах життєвого циклу SPA;
﹣ реалізувати експериментальний SPA-додаток із застосуванням
відібраних оптимізаційних технік;
﹣ провести порівняльне тестування продуктивності до та після
впровадження оптимізацій;
﹣ оцінити ефективність використаних методів та надати рекомендації
щодо їх застосування в різних контекстах.
Об’єктом досліджень є процеси розробки та функціонування
односторінкових веб-застосунків (Single Page Applications), що забезпечують
динамічну взаємодію з користувачем у веб-середовищі.
Предметом досліджень є методи та техніки оптимізації продуктивності
SPA-додатків, зокрема підходи до зменшення часу завантаження, скорочення
споживання ресурсів і підвищення швидкодії рендерингу інтерфейсних
компонентів.
Методи досліджень. Для досягнення поставленої мети застосовано такі
методи: порівняння і спостереження – під час аналізу сучасних фреймворків і
підходів до реалізації SPA-додатків, а також при вивченні особливостей їх
продуктивності в різних середовищах виконання; емпіричний аналіз та індукція
— при вивченні ефективності конкретних технік оптимізації у додатках,
створених з використанням Angular; моделювання та синтез — під час побудови
експериментального Angular-додатку з поступовим впровадженням різних
методів оптимізації з метою порівняльного аналізу; експеримент — при
проведенні вимірювань продуктивності (час завантаження, рендеринг,
споживання пам’яті); системний підхід — при оцінці взаємозв’язків між
окремими методами оптимізації та їх впливу на загальну продуктивність
8
ЧДТУ 252471.001 ПЗ
застосунку; формалізація — при описі узагальнених рекомендацій щодо
використання методів оптимізації в Angular-додатках з урахуванням
масштабованості та реальних сценаріїв використання.
Наукова новизна отриманих результатів. Удосконалено підхід до
класифікації методів оптимізації продуктивності SPA-додатків, реалізованих на
Angular, з урахуванням етапів їх життєвого циклу. Отримало подальший розвиток
уявлення про вплив архітектурних рішень Angular-додатків на продуктивність.
Практичне значення отриманих результатів. Розроблено та впроваджено
прототип SPA-додатку на Angular із використанням сучасних методів оптимізації
продуктивності, що дозволяє зменшити час завантаження та покращити
швидкодію інтерфейсу. Отримані результати можуть бути використані в розробці
продуктивних веб-застосунків, зокрема у сфері інформаційних систем та
електронних сервісів.
Особистий внесок автора. Усі результати наданої кваліфікаційної роботи,
які представлені на захист, були отримані автором особисто. Розроблено
архітектуру SPA-додатку, впроваджено ключові методи підвищення
продуктивності. Автором проведено експериментальні дослідження, аналіз
метрик і оцінку ефективності застосованих оптимізацій.
9
ЧДТУ 252471.001 ПЗ
РОЗДІЛ 1. ІСНУЮЧІ МЕТОДИ ТА ЗАСОБИ РОЗВ’ЯЗАННЯ
ПОСТАВЛЕНИХ ЗАВДАНЬ
1.1 Конкретизація завдань роботи
Однією з основних особливостей сучасних інформаційних технологій є
активне впровадження web-орієнтованих застосунків, які забезпечують
інтерактивну взаємодію з користувачем у режимі реального часу. У цьому
контексті Single Page Applications (SPA) стали важливим етапом розвитку клієнт-
серверної архітектури, адже дозволяють суттєво покращити користувацький
досвід завдяки зменшенню затримок при переході між сторінками та підвищенню
швидкодії інтерфейсу. Разом з тим, зростання складності SPA-додатків та обсягу
використовуваних даних актуалізує проблему їх оптимізації.
У межах даної магістерської роботи особлива увага приділяється
оптимізації продуктивності SPA-додатків, зокрема розроблених із використанням
Angular — одного з найбільш популярних фреймворків для побудови
односторінкових застосунків. Відповідно до поставленої мети, необхідно
вирішити низку взаємопов’язаних завдань, які у своїй сукупності забезпечують
досягнення високого рівня продуктивності таких додатків. Розглянемо кожне з
них докладніше:
﹣ проаналізувати наукові публікації та технічну документацію,
пов’язані з продуктивністю SPA. Це завдання передбачає дослідження
літератури, включаючи академічні статті, підручники, звіти, технічні
блоги та документацію фреймворків, з метою систематизації наявних
знань про фактори, що впливають на продуктивність односторінкових
застосунків. Аналіз літератури дозволяє виділити загальні підходи до
оптимізації, оцінити ефективність різних методів і зрозуміти їхню
актуальність у сучасних умовах;
﹣ класифікувати типові проблеми продуктивності, що виникають при
створенні та експлуатації SPA. У цьому завданні необхідно
виокремити та описати основні вузькі місця у продуктивності, такі як:
10
ЧДТУ 252471.001 ПЗ
надмірний обсяг JavaScript-коду, неконтрольоване повторне рендерення
компонентів, неефективне використання пам’яті, великі витрати часу на
первинне завантаження сторінки тощо. Це дозволяє чітко визначити цілі
оптимізації та орієнтуватися на вирішення конкретних проблем;
﹣ дослідити та систематизувати існуючі методи оптимізації. До цього
завдання належить опис сучасних технік, таких як lazy loading, code
splitting, tree shaking, кешування даних, оптимізація зображень і
шрифтів, використання ahead-of-time компіляції, застосування change
detection стратегій та інші. Також необхідно проаналізувати їхню
ефективність у контексті Angular-додатків та сформувати рекомендації
щодо використання;
﹣ розробити прототип SPA-додатку з реалізацією методів оптимізації.
Це завдання передбачає практичне впровадження досліджених методів у
тестовому проєкті, що дозволяє перевірити їхню ефективність у
реальних умовах. У якості середовища розробки обрано Angular, що
забезпечує широку підтримку сучасних засобів оптимізації;
﹣ оцінити ефективність запропонованих рішень за допомогою
інструментів аналізу продуктивності. Завданням є вимірювання
ключових показників продуктивності, таких як First Contentful Paint
(FCP), Time to Interactive (TTI), Largest Contentful Paint (LCP), а також
загальний час завантаження додатку. Аналіз проводиться до та після
впровадження методів оптимізації з метою верифікації покращень.
Аналіз особливостей SPA
Задля розуміння проблем пов’язаних з оптимізацією SPA, доцільно
ознайомитись з особливостями архітектури односторінкових додатків та
відмінностями від багатосторінкових додатків (MPA).
Single Page Application (SPA) — це архітектурний підхід до створення веб-
додатків, за якого основна логіка роботи переноситься на клієнтську частину. На
відміну від традиційних багатосторінкових додатків (Multi Page Applications,
MPA), де кожна зміна сторінки передбачає повне завантаження нового HTML-
11
ЧДТУ 252471.001 ПЗ
документа з сервера, у SPA відбувається динамічне оновлення лише необхідних
частин інтерфейсу. Це забезпечується за допомогою JavaScript-фреймворків,
таких як Angular, React чи Vue [9].
Архітектурні особливості SPA:
﹣ єдиний HTML-документ: додаток завантажує базовий index.html один
раз, а подальші переходи між “сторінками” відбуваються шляхом зміни
стану клієнтського застосунку;
﹣ керування маршрутизацією на клієнтській стороні: навігація
здійснюється за допомогою JavaScript-роутера, що дозволяє уникнути
повторних HTTP-запитів до сервера для кожної сторінки;
﹣ взаємодія з сервером через API: основний обмін даними відбувається у
форматі JSON через REST або GraphQL, тоді як HTML-розмітка
генерується на клієнті;
﹣ високе навантаження на клієнтську сторону: більшість обчислень,
візуалізація та рендеринг інтерфейсу виконується у браузері.
Таблиця 1.1
Відмінності між SPA та MPA
Характеристика MPA SPA
Завантаження сторінок Кожен перехід виконує Відбувається лише один
новий HTTP-запит і початковий запит, далі
перезавантажує сторінку працює клієнтська
маршрутизація
Розподіл логіки Більшість логіки — на Значна частина логіки —
сервері на клієнті
Продуктивність Повільніший час відгуку Вищий час відгуку після
через повне першого завантаження,
перезавантаження але швидка робота надалі
12
ЧДТУ 252471.001 ПЗ
Продовження таблиці 1.1
SEO-оптимізація Просте індексування Необхідні додаткові
пошуковими системами засоби (SSR,
Prerendering)
Складність розробки Традиційні підходи, Вища складність,
простіше налагоджувати потребує фреймворків та
оптимізації
Споживання ресурсів Менші вимоги до Більші вимоги до
браузера, більші — до клієнтських ресурсів
сервера (CPU, RAM)
Аналіз і визначення основних метрик
Розуміння та вимірювання основних показників продуктивності дозволяє не
лише об’єктивно оцінювати стан додатку, а й виявляти “вузькі місця”, що
потребують оптимізації. Для SPA, створених на Angular чи інших сучасних
фреймворках, метрики продуктивності є фундаментом подальших рішень щодо
архітектури, вибору інструментів і технік оптимізації.
Основні показники продуктивності у Front-end:
﹣ час першого відображення (First Paint, FP / First Contentful Paint,
FCP). Вимірює момент, коли користувач вперше бачить будь-який вміст
на екрані. У SPA цей показник напряму залежить від розміру
початкового бандлу, ефективності завантаження ресурсів та
використання механізмів попереднього рендерингу (наприклад, Angular
Universal);
﹣ час до інтерактивності (Time to Interactive, TTI). Визначає момент,
коли сторінка стає повністю інтерактивною: користувач може
взаємодіяти з кнопками, формами та іншими елементами без помітних
затримок. Для SPA критичним фактором є ефективність ініціалізації
фреймворку та виконання JavaScript-коду;
13
ЧДТУ 252471.001 ПЗ
﹣ індекс швидкості (Speed Index, SI). Показує, наскільки швидко
завантажується візуальний контент сторінки. Ця метрика дозволяє
оцінити плавність та поступовість відображення інтерфейсу;
﹣ FPS (Frames Per Second). Частота кадрів при анімаціях та взаємодії з
інтерфейсом. Якщо FPS падає нижче 60, користувач сприймає роботу
додатку як “підвисання”. В Angular це може бути пов’язано з
неефективним механізмом Change Detection або надмірною кількістю
DOM-операцій;
﹣ затримки рендерингу (Rendering/Script Execution Delay). Час, який
витрачає браузер на обробку JavaScript і відмальовування елементів.
SPA часто страждають від “блокуючих” скриптів, що ускладнює
відображення інтерфейсу;
﹣ розмір та структура бандлу. Великі бандли призводять до збільшення
часу початкового завантаження. Для Angular критично важливими є
використання tree-shaking, lazy loading та code splitting для зменшення
кінцевого обсягу завантажуваного коду;
﹣ використання пам’яті (Memory Usage). Надмірне споживання
оперативної пам’яті може призвести до деградації продуктивності на
мобільних пристроях. Витоки пам’яті (memory leaks) особливо
небезпечні у SPA через тривалий життєвий цикл додатку без
перезавантаження сторінки;
﹣ Input Delay (First Input Delay, FID / Interaction to Next Paint, INP).
Вимірює час між дією користувача (наприклад, кліком) та фактичною
реакцією інтерфейсу. Це показник безпосереднього користувацького
досвіду, що часто страждає через важкі обчислення в головному потоці
JavaScript.
Таким чином, визначення та аналіз зазначених метрик дозволяє комплексно
оцінити ефективність роботи SPA. Саме вони формують основу для подальшої
оптимізації та є об’єктивними орієнтирами під час порівняння різних методів і
засобів підвищення продуктивності у frontend-розробці.
14
ЧДТУ 252471.001 ПЗ
1.2 Актуальні проблеми, що виникають в процесі виконання завдань
Попри численні переваги односторінкових додатків, пов’язані з плавністю
роботи інтерфейсу та зручністю користувацької взаємодії, архітектура SPA
створює специфічні виклики щодо продуктивності. Це призводить до появи низки
проблем, які можуть негативно впливати на досвід користувача.
Основні проблеми продуктивності в SPA:
﹣ великий початковий час завантаження (Initial Load Time). SPA
зазвичай завантажують великий бандл JavaScript, що включає ядро
фреймворку, бізнес-логіку, стилі та залежності. У Angular це може
призводити до значного збільшення часу відображення першого
контенту (FCP) та затримки інтерактивності (TTI), особливо на
мобільних пристроях з обмеженими ресурсами;
﹣ надмірна кількість DOM-операцій. Постійні зміни у великому DOM-
дереві уповільнюють рендеринг та викликають лаги інтерфейсу. У
Angular додатковим фактором є механізм Change Detection, який за
замовчуванням перевіряє всі зв’язані з компонентами дані, навіть якщо
вони не змінилися;
﹣ витоки пам’яті (Memory Leaks). Довготривала робота SPA без
перезавантаження сторінки може призводити до накопичення об’єктів у
пам’яті. Типові причини: невчасне відписування від RxJS-стрімів,
некоректне керування таймерами або підписками на DOM-події;
﹣ низька продуктивність під час анімацій та інтерактивних дій. Якщо
FPS падає нижче 60 кадрів на секунду, користувач сприймає додаток як
“гальмуючий”. Це може бути спричинено складними Angular-
анімаціями або частими перерахунками стану компонентів;
﹣ проблеми з SEO та індексацією. Оскільки контент SPA генерується на
клієнті, пошукові системи часто не індексують його належним чином.
Angular вирішує це завдяки Angular Universal (SSR), але додаткова
інтеграція створює складність у підтримці;
15
ЧДТУ 252471.001 ПЗ
﹣ високе навантаження на головний потік (Main Thread). Виконання
великого обсягу JavaScript-коду блокує головний потік браузера, що
безпосередньо впливає на швидкість відгуку на дії користувача (Input
Delay). Це особливо критично для мобільних пристроїв з обмеженими
CPU-ресурсами.
Методи оптимізації продуктивності на рівні клієнта
Оптимізація продуктивності у Single Page Applications значною мірою
залежить від ефективного використання клієнтських ресурсів. Оскільки основне
навантаження у SPA зосереджене на браузері, саме клієнтська частина визначає,
наскільки швидко та стабільно працюватиме додаток. Для Angular це особливо
актуально, адже початковий бандл часто включає значний обсяг коду, а механізми
зміни стану та рендерингу потребують ретельного налаштування.
Наприклад, для покращення такого показника як час першого
відображення (FCP), використовуються засоби спрямовані на оптимізацію
завантаження додатка:
﹣ мініфікація та стиснення коду: видалення коментарів, пробілів та
заміна довгих ідентифікаторів на короткі (здійснюється інструментами
типу Terser);
﹣ tree shaking: усунення невикористаного коду на етапі збірки. В Angular
цей процес інтегровано у Webpack і використовується за замовчуванням;
﹣ code splitting: розділення коду на менші фрагменти, що завантажуються
лише за потреби. Це зменшує час початкового завантаження;
﹣ lazy loading: відкладене завантаження модулів або компонентів, які
потрібні не одразу. Angular підтримує lazy loading для модулів через
loadChildren у маршрутах.
Для зниження часу повторного завантаження та покращення індексу
швидкості (SI) застосовуються методи, що мінімізують кількість мережевих
запитів:
﹣ HTTP-кешування: повторно використовує вже завантажені ресурси без
звернення до сервера [18];
16
ЧДТУ 252471.001 ПЗ
﹣ service workers: зберігають статичні ресурси локально, забезпечуючи
швидке відкриття додатку навіть офлайн;
﹣ Content Delivery Network (CDN): доставляє контент із найближчого
географічного сервера, зменшуючи затримку (latency).
Щоб покращити час до інтерактивності (TTI) та зменшити затримки
рендерингу, необхідно оптимізувати взаємодію додатку з API:
﹣ дедуплікація запитів: запобігання надмірному завантаженню
однакових даних;
﹣ кешування результатів: повторне використання даних, які вже були
отримані, зменшує затримки при оновленні інтерфейсу;
﹣ обмеження частоти оновлень (debounce/throttle): знижує
навантаження на головний потік під час активної взаємодії користувача.
Для покращення таких показників, як FPS і Rendering Delay,
застосовуються методи зниження обсягів завантажуваних ресурсів і підвищення
ефективності їх обробки:
﹣ оптимізація зображень: використання сучасних форматів (WebP, AVIF)
і адаптивного завантаження;
﹣ асинхронне завантаження шрифтів і стилів: запобігає блокуванню
рендерингу сторінки;
﹣ видалення невикористаних CSS: зменшує час обробки стилів
браузером;
﹣ prefetching та preloading: підготовка до завантаження ресурсів, які,
ймовірно, знадобляться далі.
Щоб покращити інтерактивність та зменшити Input Delay, необхідно
мінімізувати навантаження на головний потік браузера:
﹣ web workers: дозволяють виконувати складні обчислення у фонових
потоках, не блокуючи UI;
﹣ оптимізація алгоритмів: скорочення вкладених циклів і важких
обчислень без потреби;
17
ЧДТУ 252471.001 ПЗ
﹣ throttle та debounce: зменшують частоту викликів подій (scroll, resize,
input), що дозволяє зберігати стабільний FPS і швидкий відгук
інтерфейсу.
1.3 Методи та засоби, які вже використовуються для усунення проблем
та виконання завдань
У процесі розроблення односторінкових веб-додатків (Single Page
Applications, SPA) важливим аспектом є ефективне використання ресурсів
клієнтського середовища. Продуктивність SPA безпосередньо впливає на ключові
показники якості — Largest Contentful Paint (LCP), Interaction to Next Paint (INP) та
Cumulative Layout Shift (CLS).
Для їхнього покращення сучасні фреймворки впроваджують різноманітні
методи оптимізації, серед яких — серверний рендеринг (SSR), розбиття коду
(code splitting), ліниве завантаження (lazy loading), гідратація (hydration),
реактивне оновлення даних та зменшення розміру бандлу.
У цьому підрозділі розглянуто три популярні фреймворки — React, Vue.js
та Svelte — з погляду їхніх підходів до оптимізації продуктивності SPA.
React
React є найпоширенішим інструментом для побудови SPA, який базується
на концепції віртуального DOM та компонентного підходу. Його механізм
оновлень дозволяє мінімізувати кількість змін у реальному DOM, що знижує
навантаження на браузер. Основні методи оптимізації продуктивності у React:
﹣ code splitting за допомогою React.lazy та Suspense — зменшує розмір
початкового бандлу, завантажуючи компоненти лише за потреби;
﹣ мемоізація компонентів (React.memo, useMemo, useCallback) —
дозволяє уникати непотрібних ререндерів;
﹣ concurrent rendering (React 18) — виконує оновлення асинхронно,
забезпечуючи швидшу реакцію інтерфейсу;
﹣ SSR та ISR (через Next.js) — серверний рендеринг з наступною
гідратацією дає змогу скоротити час першого відображення (Time to
18
ЧДТУ 252471.001 ПЗ
First Paint) та покращити LCP;
﹣ Static Site Generation (SSG) — використовується для попереднього
рендерингу сторінок, що мінімізує навантаження на клієнтську частину.
React характеризується гнучкістю та широким набором інструментів для
оптимізації, однак вимагає від розробника ретельного налаштування архітектури
для досягнення стабільної продуктивності.
Vue.js
Vue.js є прогресивним фреймворком, який завдяки своїй реактивній
системі на основі Proxy забезпечує високу продуктивність навіть без додаткових
оптимізацій. Його основна перевага полягає у точному відстеженні залежностей
— Vue оновлює лише ті частини DOM, які реально змінилися, що позитивно
впливає на показник INP.
Методи оптимізації у Vue.js:
﹣ lazy loading компонентів — реалізований на рівні ядра фреймворку, дає
змогу зменшити час завантаження початкової сторінки;
﹣ code splitting та tree-shaking — реалізовані через збирачі Vite або
Webpack, скорочують обсяг JavaScript-коду;
﹣ Server-Side Rendering (через Nuxt.js) — зменшує час до першого
відображення (First Contentful Paint);
﹣ hydration — після SSR дозволяє браузеру «активувати» статичний
HTML без повного перерендеру;
﹣ оптимізація шаблонів — Vue компілює шаблони у високоефективні
рендер-функції, що зменшує обсяг обчислень під час оновлення
інтерфейсу.
Завдяки вбудованій реактивності та зручному механізму lazy loading, Vue
забезпечує чудові показники LCP і INP, залишаючись простим у налаштуванні.
Svelte
Svelte є відносно новим, але технічно унікальним фреймворком, що
відрізняється від React і Vue відсутністю віртуального DOM.
19
ЧДТУ 252471.001 ПЗ
Замість цього Svelte компілює компоненти у чистий JavaScript на етапі
збірки, перетворюючи декларативний код безпосередньо у високоефективні
інструкції маніпуляції DOM.
Методи оптимізації у Svelte:
﹣ відсутність runtime — зменшує споживання пам’яті та прискорює
ініціалізацію;
﹣ мінімальний розмір бандлу (часто <50 КБ) — забезпечує швидке
завантаження та низький Time to Interactive (TTI);
﹣ reactivity by assignment — зміни у змінних автоматично оновлюють
інтерфейс без обробки віртуального DOM;
﹣ code splitting та prefetching (через SvelteKit) — дозволяють
завантажувати сторінки та модулі наперед;
﹣ SSR / SSG — SvelteKit підтримує серверний рендеринг і генерацію
статичних сторінок із наступною гідратацією, що покращує LCP і FID.
Проведений аналіз показує, що всі три фреймворки застосовують ефективні
методи оптимізації продуктивності SPA, проте кожен з них має власну концепцію
їхньої реалізації:
﹣ React — пропонує найгнучкішу екосистему оптимізацій, але вимагає
детального архітектурного планування;
﹣ Vue.js — має вбудовану реактивність і механізми оптимізації, які
забезпечують високі показники продуктивності навіть без додаткових
налаштувань;
﹣ Svelte — демонструє найвищу ефективність завдяки компіляційній
моделі та мінімальному runtime, що дозволяє досягти найкращих
результатів LCP та INP серед сучасних фреймворків.
20
ЧДТУ 252471.001 ПЗ
Висновки до розділу
У результаті проведеного аналізу встановлено, що продуктивність Single
Page Applications (SPA) є одним із ключових чинників, який безпосередньо
впливає на користувацький досвід та ефективність роботи веб-додатків. На
відміну від традиційних багатосторінкових застосунків (MPA), SPA мають
специфічну архітектуру, що забезпечує швидку взаємодію з користувачем, але
водночас створює нові виклики, пов’язані із завантаженням великого обсягу
JavaScript-коду, рендерингом на клієнті та управлінням станом.
Дослідження основних показників продуктивності — таких як час першого
відображення, індекс інтерактивності, частота кадрів (FPS), затримки рендерингу
та розмір бандлу — дало змогу визначити ключові напрями оптимізації. Розгляд
існуючих методів та засобів, включно з оптимізацією завантаження ресурсів,
ефективним рендерингом компонентів, мінімізацією коду та використанням
кешування, показав, що досягнення високої продуктивності вимагає
комплексного підходу.
Таким чином, проведення подальших досліджень у цій галузі є необхідним
для розроблення нових або вдосконалення існуючих методів оптимізації, які
враховуватимуть особливості сучасних фреймворків, зокрема Angular. Це
дозволить забезпечити стабільну роботу SPA навіть за складних умов виконання,
скоротити час відгуку інтерфейсу та підвищити загальну ефективність фронтенд-
додатків.
21
ЧДТУ 252471.001 ПЗ
РОЗДІЛ 2. ТЕОРЕТИЧНІ ТА ЕКСПЕРИМЕНТАЛЬНІ ДОСЛІДЖЕННЯ
2.1 Теоретичні дослідження
Метою теоретичних досліджень є встановлення закономірностей, що
визначають продуктивність односторінкових веб-додатків (SPA), а також
побудова формальної моделі, яка описує вплив архітектурних рішень Angular на
часові та ресурсні характеристики роботи системи. Теоретичний аналіз дозволяє
визначити ключові взаємозв’язки між структурою SPA, механізмами рендерингу,
організацією потоків даних і поведінкою браузерного середовища, а також
сформувати гіпотезу про можливість підвищення ефективності веб-додатків за
допомогою сучасних методів оптимізації.
Основними підзадачами дослідження є:
﹣ мінімізація часу початкового завантаження додатка;
﹣ зменшення затримок рендерингу компонентів;
﹣ зниження навантаження на головний потік браузера;
﹣ оптимізація обсягу та кількості мережевих запитів;
﹣ покращення загального користувацького досвіду (UX).
Математична модель задачі оптимізації
Розглянемо SPA як систему:
S =〈C, D, R, P〉, (2.1)
де
﹣ C — множина компонентів користувацького інтерфейсу;
﹣ D — потік даних і HTTP-запитів;
﹣ R — клієнтські ресурси (JS, CSS, зображення та кеш);
﹣ P — показники продуктивності.
Введемо вектор метрик продуктивності:
P = {TFCP, TTTI, TLCP, FPS, Sbundle }, (2.2)
де
22
ЧДТУ 252471.001 ПЗ
﹣ TFCP — час першого відображення контенту (First Contentful Paint);
﹣ TTTI — час до інтерактивності (Time To Interactive);
﹣ TLCP — час найбільшого завантаженого елемента (Largest Contentful
Paint);
﹣ FPS — частота відтворення кадрів;
﹣ Sbundle — розмір кінцевого пакета JavaScript.
Задача оптимізації формулюється як мінімізація функції:
F = ω1TFCP + ω (2.3)
2TTTI + ω3TLCP + ω4Sbundle ﹣ω5FPS ,
де
ωi — вагові коефіцієнти, що визначають значущість кожної метрики.
Обмеження та критерії ефективності
Задача оптимізації виконується за таких обмежень:
﹣ функціональність додатка зберігається: Fbase = Fopt
﹣ не погіршується зручність використання (UX): UXopt ≥ UXbase
﹣ застосовані оптимізації не ускладнюють підтримку коду: Cmaintain ≈ const
Критеріями ефективності рішень є:
﹣ скорочення часу завантаження на 10–40%;
﹣ зменшення розміру бандлу щонайменше на 20%;
﹣ усунення макрозатримок (>50 ms) у головному потоці;
﹣ стабільна частота кадрів не нижче 55–60 FPS.
Таким чином, підвищення продуктивності SPA може бути подано як
формальну задачу оптимізації. Модель продуктивності дозволяє системно
оцінювати ефективність кожного методу оптимізації та застосовувати їх у
комплексі. Отримана математична постановка задає основу для подальшого
теоретичного аналізу та побудови експериментальної моделі.
Поглиблений розбір методів оптимізації продуктивності
Структурний метод оптимізації. Структурні методи оптимізації
передбачають зміну організації програмної системи, її внутрішніх залежностей,
способу завантаження модулів та взаємодії компонентів. Основна ідея полягає у
23
ЧДТУ 252471.001 ПЗ
тому, що продуктивність SPA може бути покращена шляхом оптимального
формування структури додатку: поділу коду на фрагменти, зменшення зв’язності
компонентів, зміни порядку виконання операцій та оптимізації архітектурних
залежностей.
Такі методи не змінюють параметри виконання окремих елементів, а
трансформують архітектурну модель, роблячи її більш гнучкою, модульною та
придатною до поділу навантаження. До структурного методу належать такі
об’єкти оптимізації в Angular:
Lazy Loading — це стратегія оптимізації, при якій частини застосунку
(модулі, компоненти, ресурси) завантажуються лише тоді, коли вони реально
потрібні. Angular дозволяє розділити додаток на незалежні функціональні блоки
(feature modules), завантаження яких відкладається до переходу користувача на
відповідний маршрут [3].
При Lazy Loading Angular не включає всі модулі у головний бандл (main.js).
Натомість кожен лениво завантажуваний модуль компілюється в окремий
JavaScript-файл, який завантажується динамічно за необхідності [16].
Вигоди Lazy Loading:
﹣ зменшення часу початкового завантаження;
﹣ оптимізація мережевих ресурсів;
﹣ підвищення продуктивності UX;
﹣ масштабованість.
Code Splitting — це техніка автоматичного розбиття коду на окремі
фрагменти (chunks) на етапі збірки. В Angular за це відповідає Webpack, який
входить до Angular CLI. Code Splitting працює разом з Lazy Loading — кожен
ленивий модуль перетворюється на окремий chunk.
Angular виконує Code Splitting автоматично, коли в маршрутах
використовуються динамічні імпорти. Результатом є окремий файл, який НЕ
потрапляє в основний бандл і завантажується динамічно лише при переході на
відповідний маршрут.
Окрім продуктивності, Lazy Loading сприяє архітектурній структурованості
24
ЧДТУ 252471.001 ПЗ
додатку:
﹣ модулі мають чітку зону відповідальності (feature modularity);
﹣ полегшується рефакторинг;
﹣ підвищується можливість повторного використання частин застосунку;
﹣ знижується зв’язність компонентів (loose coupling).
Lazy Loading та Code Splitting є фундаментальними техніками оптимізації
для Angular-додатків, спрямованими на:
﹣ зменшення часу завантаження сторінки;
﹣ оптимізацію обсягу JavaScript;
﹣ підвищення швидкодії та продуктивності SPA;
﹣ покращення користувацького досвіду;
﹣ побудову масштабованої архітектури.
Застосування цих підходів є обов’язковим для великих корпоративних
додатків і є одним із ключових інструментів performance optimization в Angular.
Resolver – це механізм маршрутизації, який дозволяє завантажити дані
перед активацією маршруту. Вони забезпечують передачу до компонента вже
підготовлених даних, зменшуючи кількість асинхронних операцій усередині
компонентів та покращуючи досвід користувача. Resolver виконується перед тим,
як Angular активує маршрут, і може блокувати навігацію до моменту отримання
даних.
Основні переваги:
﹣ підвищення продуктивності за рахунок контрольованого завантаження
даних;
﹣ уникнення “порожнього рендеру” компонентів під час очікування даних.
﹣ перенесення логіки отримання даних із компонентів у маршрути —
зменшення навантаження на change detection;
﹣ покращення UX – користувач одразу бачить повністю готову сторінку;
﹣ підвищення індексу швидкості (SI);
﹣ менше підписок (subscribe) у компонентах → менще ризику memory
25
ЧДТУ 252471.001 ПЗ
leaks;
﹣ інтегрується з Lazy Loading – маршрути підтягують дані тільки при
потребі.
Standalone Components — це архітектурний підхід, представлений у
Angular починаючи з версії v14 (стабільний з v15), який дає змогу створювати
компоненти, директиви та пайпи без необхідності оголошувати їх у NgModule
(тобто без прив’язки до конкретного модуля). Цей підхід є ключовою віхою
еволюції Angular та спрямований на підвищення продуктивності, зменшення
складності та покращення масштабованості застосунків [2].
У класичній Angular-архітектурі кожен компонент був оголошений у модулі
(declarations), а залежності — у imports. Це створювало низку проблем:
﹣ надмірна складність структури проєкту (надлишкова кількість
NgModule);
﹣ ускладнення lazy loading та повторного використання компонентів;
﹣ збільшення часу компіляції та збирання;
﹣ важчий вхідний поріг для нових розробників;
﹣ зайва бюрократія декларацій у коді.
Концепція standalone компонента була створена для вирішення цих
незручностей. Такий компонент є самодостатнім (self-contained), тобто може
існувати та використовуватись без NgModule. Він оголошується за допомогою
параметра standalone: true. Його перевагами є:
﹣ відсутність декларацій у модулях (менше коду);
﹣ прямий імпорт компонентів;
﹣ краща підтримка lazy loading;
﹣ краща tree-shaking оптимізація.
Звідси випливає позитивний вплив на оптимізацію SPA:
﹣ зменшує час початкового завантаження застосунку;
﹣ зменшує кількість проміжних абстракцій → швидший change detection
та простіші залежності.
26
ЧДТУ 252471.001 ПЗ
Параметричний метод оптимізації. Параметричні методи оптимізації
полягають у зміні режимів роботи або параметрів механізмів, які визначають
поведінку додатку без зміни його структури. Основна мета — зменшити обсяг
непотрібних операцій, скоротити кількість реакцій на події або підвищити
ефективність циклів оновлення інтерфейсу.
У таких методах змінюються властивості виконання, а не архітектурні
залежності. Параметрична оптимізація є одним із найбільш дієвих підходів у
системах із частими оновленнями, таких як Angular. До параметричного методу
належать такі об’єкти оптимізації в Angular:
Механізм виявлення змін (Change Detection) в Angular є ключовим
елементом реактивної архітектури фреймворку. Він відповідає за оновлення DOM
після зміни стану компонентів або даних у додатку. Завдяки цьому Angular
підтримує декларативну модель програмування, де інтерфейс автоматично реагує
на зміну даних [1].
У великих SPA-додатках часті зміни стану (потоки подій, відповіді HTTP,
таймери, взаємодія з користувачем) можуть запускати численні перерендери. Це
призводить до:
﹣ зростання кількості обчислень;
﹣ зайвих оновлень DOM;
﹣ деградації продуктивності UI.
Тому Angular надає механізми контролю над змінами, серед яких ключовим
є ChangeDetectionStrategy. Angular підтримує дві стратегії перевірки змін
особливості яких розкриті в таблиці 2.1. Можливість керування цими процесами
дозволяє зменшити навантаження на головний потік браузера та підвищити
швидкодію інтерфейсу користувача. Правильний вибір стратегії перевірки змін є
особливо важливим для компонентів, що працюють з великими обсягами даних
або часто оновлюються в реальному часі, оскільки безпосередньо впливає на
ефективність рендерингу та загальну продуктивність SPA-додатку.
Таблиця 2.1
27
ЧДТУ 252471.001 ПЗ
Стратегії Change Detection
Стратегія Опис Використання
Default Angular перевіряє зміни рекурсивно Простий варіант, але менш
для всіх компонентів дерева при ефективний
будь-якій події
OnPush Перевіряє зміни тільки коли Використовується для
змінюється input компонента, оптимізації
відбувається подія всередині або
змінюється observable/Promise
При використанні OnPush Angular вважає компонент “чистим” (Pure
Component), тобто його стан не змінюється самостійно. Зміни в ньому
відбуваються лише за чітко визначених умов [4].
Angular виконує change detection, якщо:
﹣ змінилося значення одного з @Input();
﹣ викликана подія в компоненті (наприклад, (click));
﹣ компонент отримав нові дані з Observable/Pipe async;
﹣ ручний запуск markForCheck() або detectChanges().
Angular не перевіряє компонент при зміні локальних змінних або мутації
об’єктів “на місці”.
Вплив OnPush на продуктивність:
﹣ зменшує кількість викликів Change Detection;
﹣ мінімізує навантаження на процесор;
﹣ зменшує кількість оновлень DOM;
﹣ дозволяє масштабувати великі додатки;
﹣ покращує FPS у складних UI (таблиці, списки, графіки).
Також цей підхід сприяє впровадженню принципів функціонального
програмування та іммутабельності даних.
28
ЧДТУ 252471.001 ПЗ
Оптимізація повторюваних списків за допомогою trackBy
В Angular директива *ngFor використовується для рендерингу списків у
темплейтах. За замовчуванням Angular при будь-якій зміні масиву повторно
створює DOM-елементи для кожного елементу списку, навіть якщо більшість із
них залишилися без змін. Це може значно знижувати продуктивність при роботі з
великими списками.
Використання функції trackBy дозволяє Angular відслідковувати елементи
списку за унікальним ідентифікатором і перевикористовувати DOM-елементи без
повторного рендерингу.
Переваги:
﹣ менше операцій з DOM → вища продуктивність;
﹣ краще реагує на оновлення даних у великих таблицях та списках;
﹣ перевикористовує існуючі DOM елементи;
﹣ особливо ефективно при оновленні лише частини списку.
Ситуації в яких буде доцільно використовувати trackBy:
﹣ великі списки (100+ елементів);
﹣ часті оновлення масиву даних;
﹣ таблиці, списки в реальному часі.
Оптимізаційний ефект:
﹣ зменшує навантаження на Change Detection;
﹣ підвищує FPS у складних інтерфейсах;
﹣ уникає зайвого мерехтіння DOM;
﹣ значно покращує продуктивність у поєднанні з OnPush.
Функціональний (алгоритмічний) метод оптимізації. Алгоритмічні
методи оптимізації спрямовані на вдосконалення алгоритмів обробки даних,
виконання коду або формування фінального JavaScript-бандла. Ці методи не
змінюють структуру додатку, але покращують ефективність його внутрішніх
процедур — від компіляції до виконання.
У SPA важливим є мінімізація складності алгоритмів, уникнення
дублювання операцій та усунення невикористаного коду, що знижує
29
ЧДТУ 252471.001 ПЗ
навантаження на процесор і пам’ять під час виконання. До алгоритмічного методу
належать такі об’єкти оптимізації в Angular:
Tree-Shaking — це оптимізаційна техніка на етапі збирання JavaScript-
додатків, що автоматично видаляє мертвий код (dead code elimination) — тобто ті
частини коду, які не використовуються під час виконання програми. Основна
мета — зменшення розміру фінального бандла та прискорення завантаження SPA.
Сучасні SPA-додатки використовують численні залежності, бібліотеки та модулі
[7].
Це часто призводить до:
﹣ надмірного обсягу клієнтського JavaScript;
﹣ довшого часу завантаження сторінки (Time to Interactive);
﹣ збільшеного часу парсингу та інтерпретації JS;
﹣ зниження показників продуктивності (особливо на мобільних
пристроях).
Tree-Shaking усуває зайвий код ще до доставлення на клієнт, тим самим
підвищуючи ефективність.
В Angular Tree-Shaking виконується автоматично за допомогою Angular CLI,
яке базується на Webpack і компіляторі Angular Ivy. Оптимізація застосовується
під час production-збірки. Tree-Shaking є невід’ємною частиною performance-
driven архітектури Angular і поєднується з іншими оптимізаційними підходами.
RxJS: керування потоками даних в Angular
RxJS (Reactive Extensions for JavaScript) — це бібліотека для роботи з
асинхронними потоками даних на основі патерну Observer. В Angular вона
відіграє фундаментальну роль, адже застосунок будується на реактивній моделі,
де події, HTTP-запити, введення користувача та таймери розглядаються як
потоки.
У великих SPA-додатках неконтрольоване використання потоків [5] може
призвести до:
﹣ надмірної кількості підписок;
﹣ витоків пам’яті (memory leaks);
30
ЧДТУ 252471.001 ПЗ
﹣ дублювання HTTP-запитів;
﹣ перевантаження change detection;
﹣ затримок інтерфейсу.
Тому оптимальне управління потоками RxJS є важливим аспектом
продуктивності.
Розглянемо ключові підходи оптимізації в RxJS:
Правильне керування підписками (unsubscribe).
У RxJS кожен метод .subscribe() створює підписку, що утримує ресурси в
пам’яті. Якщо від них не відписуватись, виникають витоки пам’яті. Для
оптимізації використовуються:
﹣ оператор takeUntil();
﹣ оператор take(1);
﹣ Async Pipe.
Дедублікація та кешування потоків (shareReplay)
Кожен підписник Observable типу HTTP створює новий запит → зайве
навантаження на сервер. Використання shareReplay() кешує результат і розподіляє
один потік між кількома підписниками.
Переваги цього методу:
﹣ запобігає дублюванню запитів;
﹣ зменшує навантаження на сервер;
﹣ підвищує продуктивність UI.
Контроль частоти подій (debounceTime)
Події введення з клавіатури, кліки та скролінг створюють величезні потоки
даних. Це може перевантажити обчислення та сервер, якщо дозволити
необмежено викликати методи пов’язані з обробкою цих подій.
Оператор debounceTime() — затримує обробку, поки користувач не припинить
вводити дані. В якості аргумента можна вказати відрізок часу в мілісекундах,
впродовж якого подіїї будуть “ігноруватись”. Цей оператор часто
використовується у елементах автопошуку, фільтрах, кнопках підтвердження і т.
п.
31
ЧДТУ 252471.001 ПЗ
Ресурсний метод оптимізації. Ресурсні методи оптимізації спрямовані на
раціональне використання обчислювальних ресурсів браузера — процесора,
пам’яті, мережевої пропускної здатності та часу головного потоку. У межах таких
методів важливим є перенесення частини обчислень у фонові потоки або
зниження навантаження на головний потік, який відповідає за рендеринг та
взаємодію з користувачем.
Ресурсна оптимізація є критично важливою для SPA з інтенсивною
обробкою даних або великою кількістю одночасних операцій.До ресурсного
методу належить такий об’єкт оптимізації в Angular:
Web Workers — це механізм браузера, який дозволяє виконувати важкі або
тривалі обчислення в окремому потоці від головного (UI) потоку. В Angular Web
Workers використовують для винесення ресурсоємних операцій (наприклад,
складних розрахунків, обробки великих масивів даних, парсингу JSON,
криптографії), що допомагає уникнути зависань інтерфейсу та підвищити
загальну плавність роботи застосунку [6].
Переваги:
﹣ відсутність блокування інтерфейсу користувача;
﹣ підвищена ефективність виконання складних задач;
﹣ легко інтегрується з Angular CLI;
﹣ можна використовувати з RxJS для реактивності;
﹣ працює навіть у офлайн сценаріях (PWA).
Гіпотеза теоретичного дослідження
Гіпотеза теоретичного дослідження полягає у припущенні, що
продуктивність односторінкових веб-додатків може бути суттєво підвищена
шляхом комплексного застосування структурних, параметричних, алгоритмічних
та ресурсних методів оптимізації, характерних для сучасної архітектури Angular.
Зокрема, використання ChangeDetectionStrategy.OnPush, lazy loading, code splitting,
механізмів tree-shaking, оптимізованого керування потоками RxJS, Web Workers і
функції trackBy має зменшити навантаження на головний потік браузера,
скоротити кількість непотрібних перевірок змін, мінімізувати обсяг початкового
32
ЧДТУ 252471.001 ПЗ
JavaScript-коду та підвищити ефективність реактивної обробки подій. Внаслідок
цього очікується статистично значуще покращення інтегральних показників
продуктивності SPA — таких як First Contentful Paint, Largest Contentful Paint,
Time To Interactive, частота кадрів, розмір JavaScript-бандла та обсяг використаної
памʼяті — порівняно з неоптимізованим модульним варіантом побудови Angular-
додатка. Таким чином, гіпотеза виходить із припущення, що саме сукупна дія
оптимізаційних технік дозволяє зменшити функціональну складність системи та
підвищити ефективність її виконання в браузерному середовищі.
2.2 Експериментальні дослідження
Загальна характеристика експериментальної програмної системи
Експериментальна програмна система розроблена з метою практичного
дослідження впливу різних методів оптимізації на продуктивність
односторінкових веб-додатків (SPA). Для реалізації системи обрано сучасний
фронтенд-фреймворк Angular, який забезпечує розвинений механізм керування
змінами, маршрутизації, реактивного програмування та модульності архітектури.
Саме ці особливості роблять Angular зручним середовищем для проведення
контрольованих експериментів із продуктивністю.
Основна ідея полягає у створенні єдиного додатка, який підтримує два
режими роботи:
﹣ неоптимізований (базовий) режим — реалізує класичну архітектуру
Angular з використанням глобального Change Detection Strategy
(Default), без застосування lazy loading, Web Workers або спеціальних
підходів до оптимізації даних. Ця версія відображає традиційний підхід
до побудови SPA, який притаманний старим або неоптимізованим
проєктам;
﹣ оптимізований режим — реалізує сучасні методи підвищення
продуктивності:
﹣ використання standalone компонентів замість NgModules;
﹣ застосування ChangeDetectionStrategy.OnPush для зменшення
33
ЧДТУ 252471.001 ПЗ
кількості перевірок стану компонентів;
﹣ впровадження lazy loading для модулів і сторінок;
﹣ оптимізацію потоків даних через RxJS shareReplay, debounceTime та
async pipe;
﹣ використання trackBy у директивах ngFor;
﹣ розподіл навантаження між потоками за допомогою Web Workers;
﹣ зменшення обсягу переданих ресурсів (зображення) та застосування
tree-shaking.
Перемикання між цими двома режимами реалізовано через конфігураційний
файл середовища environment.ts, який містить булеву змінну optimized. Якщо
optimized = true, додаток компілюється в оптимізованому режимі з використанням
standalone-компонентів і lazy loading. Якщо optimized = false, застосунок
збирається у версію, що не використовує підходи для оптимізації. Такий підхід
дозволяє проводити експерименти в однакових умовах, але з різною
архітектурою, що мінімізує вплив сторонніх факторів на результати вимірювань.
Архітектура системи
Структура проєкту побудована відповідно до принципів модульності та
ізоляції функціональних частин. У складі системи виділено такі основні
компоненти:
﹣ Side Menu — бокова панель навігації, що містить переходи до основних
модулів (Dashboard, Change Detection Demo, Lazy Loading Demo тощо);
﹣ DashboardComponent — головна сторінка, на якій відображаються
загальна діаграма;
﹣ ChangeDetectionDemoComponent — модуль для демонстрації
відмінностей між стратегіями Change Detection (Default vs OnPush);
﹣ WebWorkersComponent — приклад виконання важких обчислень у
Web Worker без блокування головного потоку;
﹣ MetricsService — сервіс для збору та обчислення метрик
продуктивності (TTFI, UsedMemory);
34
ЧДТУ 252471.001 ПЗ
﹣ TMDBService — сервіс для роботи з API, який ілюструє оптимізацію
кешування через RxJS оператори (shareReplay, takeUntil, тощо).
Кожен компонент системи має уніфіковану структуру, що дозволяє
проводити цілеспрямовані експерименти. Наприклад, сторінка Change Detection
містить однакову кількість компонентів та елементів DOM, але використовує
різну стратегію відслідковування змін, що дозволяє чітко зафіксувати відмінності
у продуктивності між двома режимами.
Призначення системи
Експериментальна система створена як дослідницький стенд, який дозволяє:
﹣ порівнювати архітектурні рішення Angular за показниками
продуктивності;
﹣ визначати, які оптимізаційні підходи дають найбільший ефект;
﹣ виявляти залежності між архітектурними параметрами та поведінкою
інтерфейсу;
﹣ формувати рекомендації для розробників щодо вибору оптимальної
конфігурації SPA.
Елементи моделі та середовище експерименту
Експериментальна модель побудована на основі архітектури Angular, яка
складається з компонентів, сервісів, маршрутів і реактивних потоків. Кожен
елемент виконує чітко визначену роль у процесі відтворення реальної поведінки
SPA.
Основу моделі становить набір функціональних компонентів, об’єднаних у
дві версії:
﹣ модульна архітектура (неоптимізована) – усі компоненти
завантажуються одразу при старті програми, а зміни в DOM
перевіряються глобально за стратегією Default Change Detection;
﹣ standalone архітектура (оптимізована) – компоненти незалежні,
завантажуються динамічно через lazy loading; застосовується стратегія
OnPush, що оновлює лише ті компоненти, в яких змінився вхідний стан
або потік даних.
35
ЧДТУ 252471.001 ПЗ
Кожен компонент має власну HTML-розмітку, CSS/SCSS-стилі та
TypeScript-клас. Для забезпечення чистоти експерименту всі версії мають
однакову функціональність і обсяг логіки, але різняться архітектурно-
оптимізаційними параметрами.
Використані інструменти аналізу:
﹣ Chrome DevTools Performance — запис і візуалізація подій рендерингу,
обчислення FPS та навантаження на основний потік;
﹣ Lighthouse Report — автоматичне формування звіту з метриками
(Performance, Accessibility, Best Practices);
﹣ Angular DevTools — інструмент для аналізу тригерів Change Detection;
﹣ Performance Service — власний сервіс для збору і виводу проміжних
метрик у консолі.
Таким чином, модель експериментальної системи охоплює всі ключові
аспекти життєвого циклу SPA — від рендерингу компонентів до управління
потоками даних і оптимізації обчислень. Середовище дослідження налаштоване
таким чином, щоб забезпечити максимальну точність, повторюваність і
достовірність отриманих результатів.
Методика експерименту
Методика дослідження побудована за принципом імітаційного
моделювання, коли два варіанти однієї системи — неоптимізована та
оптимізована — виконують ідентичні сценарії взаємодії, а результати
порівнюються за низкою об’єктивних метрик.
Методика включає такі основні етапи:
﹣ підготовка середовища:
﹣ встановлення стабільної версії Angular, Node.js і всіх залежностей;
﹣ вимкнення непотрібних фонових процесів, очищення кешу браузера;
﹣ встановлення однакових умов для двох версій додатка.
﹣ збір вихідних даних:
﹣ визначення ключових метрик (FCP, LCP, Used Memory, Bundle size);
36
ЧДТУ 252471.001 ПЗ
﹣ створення базових сценаріїв користувацької взаємодії (навігація між
сторінками, оновлення даних, рендеринг таблиць).
﹣ проведення експериментів:
﹣ виконання кожного сценарію в обох версіях додатка;
﹣ запуск Lighthouse та Chrome DevTools Performance для збору метрик;
﹣ фіксація часу рендерингу, розміру бандлу, використаної пам’яті.
﹣ обробка результатів:
﹣ усереднення результатів із трьох повторних запусків для кожної
конфігурації;
﹣ обчислення відносного відсотка покращення;
﹣ побудова порівняльних таблиць та графіків.
﹣ інтерпретація результатів:
﹣ аналіз динаміки змін у показниках;
﹣ визначення методів, які дали найбільший приріст продуктивності.
Методи дослідження:
Оскільки система є програмною, дослідження проводиться за допомогою
імітаційного моделювання, яке дозволяє відтворити поведінку користувача і
браузера під час роботи SPA.
Кожен сценарій (наприклад, завантаження сторінки з таблицею або
виконання складного розрахунку у Web Worker) виконується автоматизовано
через Chrome Performance Recorder.
Результати вимірюються у реальному часі за допомогою Performance API,
який забезпечує точність до мілісекунд.
Зібрані дані обробляються аналітично:
﹣ для кожної метрики обчислюється середнє арифметичне значення;
﹣ визначається відсоткове покращення оптимізованої версії за
формулою:
, (2.4)
37
ЧДТУ 252471.001 ПЗ
де
﹣ Xbase – середнє значення показника у неоптимізованій версії,
﹣ Xopt – середнє значення показника в оптимізованій версії,
﹣ P – відсоток покращення.
Метрики оцінювання
Для кожного тестового сценарію вимірюються такі показники (табл 2.2):
Таблиця 2.2
Метрики оцінювання
Метрика Опис Одиниця
вимірюва
ння
FCP (First Contentful Paint) Час до першого відображення мс
контенту на екрані
LCP (Largest Contentful Paint) Час відображення найбільшого мс
елемента сторінки
TTI (Time to Interactive) Час, коли сторінка стає повністю мс
інтерактивною
Used JS Heap Size Використаний обсяг пам’яті під МБ
JavaScript-об’єкти
Bundle Size Розмір зібраного застосунку КБ
(main.js + assets)
Таким чином, розроблена методика забезпечує відтворюваність,
вимірюваність і аналітичну точність результатів. Вона дозволяє оцінити
ефективність кожного методу оптимізації як окремо, так і в комплексі [14].
Результати експериментальних досліджень
38
ЧДТУ 252471.001 ПЗ
Як бачимо на рис. 2.1 при запуску неоптимізованої конфігурації,
створюється невелика кількість початкових файлів. Характерною особливістю є
те, що за такої конфігурації головний файл main.js має суттєво більший за інших
розмір.
Рис. 2.1 – Результати генерації бандлу в неоптимізованій конфігурації
На рис. 2.2 можемо спостерігати, характерне для lazy-loading методу,
розбиття на велику кількість початкових файлів. Також головний файл main.js має
набагато менший розмір на рівні з іншими файлами.
Рис. 2.2 – Результати генерації бандлу в оптимізованій конфігурації
Таблиця 2.3
39
ЧДТУ 252471.001 ПЗ
Порівняння обсягів JavaScript-бандлу
Режим main.js Інші initial chunks Initial Total
Unoptimized 2.07 MB 921 KB 2.99 MB
Optimized 151.18 kB 840.5 KB 991.68 kB
Задля забезпечення більш реалістичних результатів, заміри в Lighthouse [8]
(рис. 2.3) проводились тричі для кожної конфігурації. Отримані показники були
усереднині і записані в таблицю для подальшого порівняння.
Рис. 2.3 – Приклад замірів з допомогою Lighthouse
Таблиця 2.4
40
ЧДТУ 252471.001 ПЗ
Порівняння результатів Lighthouse Performance
Метрика Unoptimized Optimized Зміна
FCP 1.1 s 0.67 s −39%
LCP 2.0 s 1.16 s −42%
Speed Index 1.1 s 0.67 s −39%
CLS 0.306 0.268 −12%
Performance Score 73 84 +11
CPU та памʼять (DevTools Performance)
Рис. 2.4 – Приклад заміру у вкладці Performance
Таблиця 2.5
41
ЧДТУ 252471.001 ПЗ
Порівняння результатів продуктивності CPU та пам’яті
Метрика Unoptimized Optimized Зміна
Max JS Heap 17.8 MB 12.8 MB −28%
Scripting 125 ms 92 ms −26%
Rendering 78 ms 35 ms −55%
Painting 10 ms 7 ms −30%
System 62 ms 33 ms −47%
Longest task 115 ms 39.49 ms −66%
Таблиця 2.6
Порівняння мережевих показників
Метрика Unoptimized Optimized Зміна
Requests 31 38 +7
Transferred 2.0 MB 1.6 MB −20%
Resources 4.5 MB 2.4 MB −47%
DOMContentLoaded 261 ms 112 ms −57%
Load event 352 ms 264 ms −25%
Finish (Idle) 5.41 s 5.28 s ≈ однаково
Аналіз результатів експериментів
Отримані дані демонструють суттєві відмінності між оптимізованою та
неоптимізованою конфігураціями SPA-додатку.
42
ЧДТУ 252471.001 ПЗ
Найбільш критична різниця полягає у значному скороченні обсягу
початкового JavaScript-коду: з 2.99 MB у неоптимізованому режимі до 0.99 MB в
оптимізованому. Зменшення на 66% різко скоротило час, необхідний для розбору,
компіляції та виконання початкових скриптів браузером. Це безпосередньо
вплинуло на показники Lighthouse: час First Contentful Paint скоротився на 39%,
Largest Contentful Paint — на 42%, а загальний Performance Score зріс з 73 до 84
балів.
Використання CPU також суттєво зменшилося. Показники Chrome
Performance свідчать про зниження часу Scripting на 26%, Rendering — на 55%, а
Painting — на 30%. Особливо важливим є зменшення найдовшої блокуючої
операції з 115 мс до 39 мс (−66%), що свідчить про значно менше блокування
основного потоку JavaScript і, відповідно, про кращу інтерфейсну реактивність
[13].
Оптимізація позитивно вплинула і на використання пам’яті. Max JS Heap
зменшився з 17.8 MB до 12.8 MB, що відповідає скороченню на 28%. Це означає
меншу кількість створених об’єктів, відсутність ініціалізації невикористаних
компонентів та зниження навантаження на роботу збирача сміття (Garbage
Collector).
Попри збільшення кількості HTTP-запитів (через lazy loading модулів),
загальний обсяг мережевого трафіку скоротився на 20%, а обсяг ресурсів — на
47%. Це свідчить про те, що більшість додаткових запитів містять дрібні чанки
коду, які не впливають на критичний шлях завантаження. Зменшення
DOMContentLoaded на 57% (з 261 мс до 112 мс) підтверджує зменшення кількості
синхронних ресурсів, які виконуються до побудови DOM.
Узагальнюючи результати експериментів, можна стверджувати, що
застосовані методи оптимізації — модульне розділення коду, lazy loading, AOT-
компіляція та оптимізація Angular-збірки — забезпечили значне покращення
загальної продуктивності SPA-додатку. Оптимізований режим демонструє більш
швидкий рендеринг, менше використання ресурсів, кращий відгук інтерфейсу та
зниження навантаження на центральний потік браузера, що підтверджує
43
ЧДТУ 252471.001 ПЗ
доцільність використання таких підходів у високонавантажених та
ресурсочутливих веб-системах [15].
44
ЧДТУ 252471.001 ПЗ
Висновки до розділу
У другому розділі було розглянуто основні теоретичні підходи та практичні
методи оптимізації продуктивності веб-додатків класу SPA, а також проведено
експериментальне дослідження їх ефективності на розробленій програмній
системі. На основі аналізу сучасних технік — таких як lazy loading, модульне
розділення коду, оптимізація зміни детекції, робота з кешуванням та
використання Web Workers — було сформовано архітектуру, що дозволяє
порівнювати неоптимізований і оптимізований режими роботи додатку.
Результати експериментів показали суттєве покращення ключових
показників продуктивності в оптимізованій конфігурації: зменшення обсягу
початкового бандлу, прискорення завантаження сторінки, зниження навантаження
на центральний потік браузера та економніше використання памʼяті. Отримані
дані підтверджують доцільність застосування розглянутих методів і доводять
їхню ефективність у підвищенні швидкодії та якості роботи SPA-додатків.
Таким чином, проведене теоретичне та експериментальне дослідження
формує основу для розроблення практичних рекомендацій щодо оптимізації
продуктивності сучасних односторінкових веб-систем.
45
ЧДТУ 252471.001 ПЗ
РОЗДІЛ 3. ВПРОВАДЖЕННЯ РЕЗУЛЬТАТІВ ДОСЛІДЖЕНЬ У
ПРАКТИКУ ПРОЄКТУВАННЯ ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ
ІНФОРМАЦІЙНИХ СИСТЕМ
3.1 Моделювання предметної області
3.1.1 Предметна область моделювання. Модель предметної області.
Словник предметної області
Предметною областю програмного забезпечення, що розробляється, є
процес отримання, відображення та дослідження даних у клієнтському веб-
застосунку класу Single Page Application (SPA), призначеному для демонстрації
практичних методів оптимізації продуктивності. Розроблений Movie Explorer
використовується як експериментальний стенд, що дозволяє оцінювати вплив
різних технік оптимізації на поведінку SPA під час роботи з реальними даними,
отримуваними з відкритого API The Movie Database (TMDB) [12]. У межах
предметної області не формується постійне серверне сховище, оскільки дані
завантажуються динамічно з зовнішнього API, що визначає характер взаємодії
між сутностями та спрощує модель зберігання.
Для формалізації предметної області сформуємо словник основних
сутностей, що беруть участь у функціонуванні системи (табл. 3.1).
Таблиця 3.1
Словник предметної області
Назва сутності Англійська Опис сутності
назва
Фільм Movie Основний інформаційний об’єкт, що містить
дані. Використовується як тестовий набір
даних у демонстраційних сценаріях.
46
ЧДТУ 252471.001 ПЗ
Продовження таблиці 3.1
Демонстраційний Demo Логічна сутність, що визначає окремий
сценарій Scenario режим роботи SPA і призначена для
демонстрації конкретного методу оптимізації
(OnPush, Lazy Loading, Web Workers тощо).
Конфігурація Optimization Набір параметрів, що задає спосіб
оптимізації Configuration функціонування SPA: optimized / unoptimized
режим, використання лінивого завантаження,
стратегія виявлення змін, застосування Web
Worker. Впливає на продуктивність
демонстраційного сценарію.
Результат пошуку Search Result Сукупність фільмів, отриманих за заданим
ключовим словом. Відображає процес
фільтрації та динамічного оновлення даних у
SPA без перезавантаження сторінки.
Маршрут Application Логічний шлях у SPA, що відповідає
застосунку Route окремому демонстраційному сценарію.
Визначає спосіб завантаження компонента
(звичайний чи lazy-loaded) і поведінкові
особливості сторінки.
Важка операція Heavy CPU-ємне обчислення, виконання якого
Operation дозволяє демонструвати вплив Web Worker
на продуктивність інтерфейсу.
Зовнішній API External API Джерело даних про фільми (TMDB), з яким
SPA взаємодіє для отримання інформації.
Модель предметної області відображає структуру взаємодії між
47
ЧДТУ 252471.001 ПЗ
основними інформаційними об’єктами Movie Explorer у контексті дослідження
продуктивності SPA. Центральним елементом є демонстраційний сценарій, який
визначає логіку роботи окремого маршруту застосунку та описує методи
оптимізації, що застосовуються в конкретному експериментальному режимі.
Кожен демонстраційний сценарій пов’язаний з певною конфігурацією
оптимізації, яка задає активні техніки: стратегію виявлення змін, використання
trackBy при відображенні списків, застосування лінивого завантаження модулів,
переміщення важких обчислень до Web Worker тощо [10].
Сутність фільм використовується як основний тип даних для демонстрації
поведінки SPA під навантаженням. Дані про фільми отримуються у вигляді
списків або результатів пошуку через зовнішній API. Оскільки дані не
зберігаються на клієнтській стороні, сутність фільму не має власного життєвого
циклу в межах SPA та існує лише як відповідь на запит у межах відповідного
сценарію.
У випадку демонстраційного маршруту, що моделює ресурсоємні
обчислення, сценарій містить сутність важкої операції, яка виконується у
головному потоці або переноситься у Web Worker. Це дозволяє оцінити вплив
зовнішнього навантаження на швидкодію інтерфейсу та виміряти різницю між
оптимізованими та неоптимізованими конфігураціями.
Таким чином, модель предметної області Movie Explorer описує структуру
експериментального SPA, побудованого з метою демонстрації впливу різних
технік оптимізації на продуктивність. Основні взаємодії формуються між
демонстраційними сценаріями, конфігурацією оптимізації та динамічно
отриманими даними про фільми, що разом створює повну функціональну картину
експериментального середовища.
3.1.2 Елементи моделювання предметної області
Для моделювання предметної області та подальшого проєктування
структури програмної системи у межах цієї роботи застосовується уніфікована
мова моделювання UML. На рисунку 3.1 представлено основні графічні елементи
UML, що використовуються для побудови діаграм.
48
ЧДТУ 252471.001 ПЗ
Рисунок 3.1 – Основні графічні символи UML
Також наведено опис елементів зв’язку UML, що застосовуються для
відображення взаємодій між сутностями моделі. Відповідні єднальні конструкції
подано на рисунку 3.2.
49
ЧДТУ 252471.001 ПЗ
Рисунок 3.2 – Єднальні елементи UML
3.1.3 Робоча область моделювання
У межах даної роботи в якості робочої області моделювання розглядається
веб-застосунок Movie Explorer. Система створена з метою демонстрації різних
методів оптимізації продуктивності. На основі предметної області сформовано
набір демонстраційних сценаріїв, що відображають характерні процеси взаємодії
користувача із SPA в умовах реального навантаження та різної конфігурації
оптимізації.
Робоча область моделювання описує загальний життєвий цикл взаємодії
користувача з додатком, включно з отриманням даних про фільми, переходами
між маршрутами, виконанням пошуку та запуском важких обчислювальних
операцій. Попри те, що застосунок не містить окремої сутності «користувач» та
не виконує аутентифікації, у рамках моделювання розглядається типовий
сценарій взаємодії анонімного відвідувача з інтерфейсом SPA.
Після відкриття застосунку користувач переходить до головного
демонстраційного сценарію, що відображає список фільмів. При активації цього
сценарію SPA надсилає запит до зовнішнього API TMDB для отримання набору
даних. Отримана інформація опрацьовується та відображається у вигляді таблиці
або списку. Користувач може виконати пошук, у результаті чого відбувається
50
ЧДТУ 252471.001 ПЗ
новий запит до API, а система формує результат пошуку з оновленим набором
фільмів.
Окремим видом взаємодії є демонстраційний сценарій із використанням
Web Worker. Користувач переходить до відповідного маршруту, де ініціюється
важка CPU-орієнтована операція (наприклад, обчислення великої кількості
ітерацій). Ця операція може бути виконана як у головному потоці, так і у Web
Worker, що дає можливість дослідити вплив перенесення обчислень на плавність
роботи інтерфейсу та загальну продуктивність SPA.
Оскільки система орієнтована на дослідження продуктивності, важливим
елементом робочої області моделювання є зміна конфігурації оптимізації.
Користувач може перемикати застосунок між оптимізованим та неоптимізованим
режимами, що впливає на методи завантаження компонентів, використання
стратегії виявлення змін, застосування механізму trackBy та інших технік. Це
дозволяє аналізувати відмінності у поведінці SPA в залежності від
використовуваних оптимізаційних підходів.
Таким чином, робоча область моделювання Movie Explorer охоплює такі
ключові процеси:
﹣ отримання та відображення списку фільмів через зовнішнє API;
﹣ виконання пошуку з динамічним оновленням даних;
﹣ перехід між демонстраційними сценаріями із різними конфігураціями
оптимізації;
﹣ ініціювання та виконання важких операцій у головному потоці або у
Web Worker;
﹣ порівняння продуктивності SPA при зміні режимів оптимізації;
﹣ моніторинг ключових метрик продуктивності (час рендерингу,
завантаження ресурсів, використання пам’яті) під час виконання
сценаріїв;
﹣ аналіз впливу механізмів керування станом і потоками подій на частоту
та тривалість циклів виявлення змін.
51
ЧДТУ 252471.001 ПЗ
3.2 Формування та аналіз вимог
3.2.1 Формування вимог до програмного забезпечення. Первинні і детальні
вимоги. Вимоги замовника і розробника. Функціональні та нефункціональні
вимоги
Формування вимог до програмного забезпечення
Вимоги замовника подаються у загальній формі та описують те, як система
повинна виглядати та функціонувати з точки зору кінцевого користувача. Такі
вимоги фіксують потреби та очікування, не містять технічних деталей та не
прив’язані до конкретних технологій. Вимоги розробника (детальні вимоги)
уточнюють первинні вимоги, описуючи систему з позиції її реалізації. Вони
містять структуровані технічні характеристики, визначають необхідні механізми
взаємодії компонентів та конкретні сценарії роботи системи.
Вимоги замовника (первинні вимоги)
Розглянемо первинні вимоги замовника:
﹣ система повинна відображати список фільмів та основну інформацію
про них із мінімальними затримками рендерингу, забезпечуючи
покращені показники FCP та LCP;
﹣ користувач повинен мати можливість виконувати пошук фільмів так,
щоб час реакції залишався низьким навіть при великому обсязі даних,
що є критичним для TTI та FPS;
﹣ інтерфейс має забезпечувати швидкий і плавний перехід між
демонстраційними режимами, не створюючи додаткового навантаження
на головний потік;
﹣ перегляд сторінки окремого фільму повинен здійснюватися з
мінімальним обсягом повторних запитів, що зменшує мережеве
навантаження і впливає на LCP;
﹣ додаток повинен дозволяти запускати сценарії демонстрації
продуктивності, включаючи важкі обчислення, що є необхідним для
експериментів з FPS, JS Heap та навантаженням CPU.
52
ЧДТУ 252471.001 ПЗ
Вимоги розробника (детальні вимоги)
Розглянемо детальні вимоги розробника:
﹣ дані про фільми повинні отримуватися з REST API TMDB, але повторні
запити мають бути мінімізовані для зменшення мережевого
навантаження та оптимізації часу відображення сторінки;
﹣ список фільмів повинен оновлюватися ефективно, без зайвих
перерендерів, що впливає на FPS та навантаження CPU;
Перехід до сторінки деталей фільму має виконуватися з використанням
кешування даних, щоб зменшити TTI та скоротити кількість HTTP-
запитів;
﹣ в оптимізованому режимі система повинна використовувати
ChangeDetectionStrategy.OnPush, що зменшує кількість непотрібних
перевірок стану і впливає на FPS, JS Heap та TTI;
﹣ для списків у оптимізованому режимі повинен застосовуватися trackBy,
що різко зменшує кількість DOM-операцій і покращує FPS;
﹣ маршрут оптимізованої архітектури повинен реалізовуватися через lazy
loading, що зменшує bundle size та покращує FCP і TTI;
﹣ сценарій Web Worker має забезпечувати виконання важких обчислень у
фоновому потоці з метою зниження затримок інтерфейсу та стабілізації
FPS;
﹣ вибір режимів optimized / unoptimized через environment.optimized
повинен впливати на структуру модулів і компонентів, дозволяючи
оцінити вплив архітектурних рішень на основні метрики.
Функціональні та нефункціональні вимоги доповнюють загальну
характеристику системи з різних боків. Функціональні вимоги описують
конкретні можливості, дії та поведінку системи в рамках сценаріїв використання.
Нефункціональні вимоги визначають якісні характеристики системи —
продуктивність, надійність, сумісність, швидкість реакції, обмеження та
стандарти, яких має дотримуватися програмний продукт.
Функціональні вимоги
53
ЧДТУ 252471.001 ПЗ
Функціональні вимоги складаються з таких вимог:
﹣ додаток повинен швидко відображати список фільмів, мінімізуючи
затримки першого рендерингу (FCP);
﹣ система повинна виконувати пошук фільмів без значного збільшення
навантаження на головний потік та без погіршення FPS;
﹣ користувач повинен мати можливість змінювати кількість
відображуваних фільмів так, щоб інтерфейс залишався плавним;
﹣ окрема сторінка фільму повинна відкриватися без тривалих повторних
запитів, оптимізуючи TTI;
﹣ у Web Worker-сценарії система повинна працювати без блокування UI,
забезпечуючи стабільний FPS.
Нефункціональні вимоги
Нефункціональні вимоги складаються з таких вимог:
﹣ інтерфейс повинен реагувати швидко та забезпечувати плавну взаємодію
навіть при великому наборі даних (вплив на FPS, TTI);
﹣ в оптимізованому режимі використання OnPush та trackBy має
забезпечувати зменшення навантаження на рендеринг і підвищувати
FPS;
﹣ система повинна коректно працювати у сучасних браузерах без
додаткових затримок у виконанні JavaScript-коду;
﹣ використання Web Worker повинно зменшувати блокування головного
потоку, і зменшуючи пікове навантаження CPU;
﹣ архітектура повинна дозволяти розширення без збільшення критичного
шляху завантаження, що впливає на bundle size;
﹣ час завантаження початкового набору компонентів повинен бути
мінімізованим (FCP, TTI);
﹣ система повинна бути стійкою до повільної відповіді API та обробляти
затримки без погіршення LCP;
﹣ обсяг мережевого трафіку повинен бути оптимізований для зменшення
54
ЧДТУ 252471.001 ПЗ
часу отримання даних.
3.2.2 Формування вимог за допомогою діаграми прецедентів
Діаграма прецедентів (рис. 3.3) відображає основні сценарії взаємодії
користувача з веб-застосунком Movie Explorer. Єдиним актором у системі є
анонімний користувач, який отримує доступ до функціональності SPA без
необхідності автентифікації. На діаграмі показано ключові прецеденти, що
охоплюють перегляд списку фільмів, виконання пошуку, зміну кількості
відображуваних елементів та перехід до детальної інформації про вибраний
фільм.
Окремою групою виділено прецеденти, пов’язані з демонстраційними
сценаріями оптимізації: перемикання режимів роботи застосунку, перехід між
різними демонстраційними сторінками та запуск важких обчислень у головному
потоці або за допомогою Web Worker. Для узагальнення цієї поведінки
застосовано спадкування прецедентів від базового сценарію «Виконання важкої
операції».
На діаграмі використані зв’язки типу extend та include. Зв’язок extend
показує, що пошук фільмів є додатковим розширенням базового сценарію
перегляду списку і виконується лише за умови введення пошукового запиту.
Зв’язок include відображає обов’язковість запиту детальної інформації до
зовнішнього API у процесі перегляду деталей фільму, що є невід’ємною частиною
цього прецеденту [11].
Таким чином, діаграма прецедентів дозволяє узагальнити основні дії
користувача та окреслити межі функціональності системи, що надалі слугуватиме
основою для побудови логічної структури та UML-діаграм взаємодії.
Взаємодія з різними режимами оптимізації та демонстраційними сценаріями
дає змогу простежити вплив архітектурних і конфігураційних рішень на
поведінку інтерфейсу та реактивність системи. Такий підхід забезпечує чітке
відокремлення функціональних можливостей прикладного рівня від
дослідницьких механізмів, що є важливим для подальшого аналізу ефективності
застосованих методів.
55
ЧДТУ 252471.001 ПЗ
Рис. 3.3 – Діаграма прецедентів
56
ЧДТУ 252471.001 ПЗ
3.2.3 Проектування логічної структури програмного комплексу
Проєктування логічної структури програмного забезпечення є наступним
етапом після формування та аналізу вимог. Якщо попередній етап зосереджувався
на описі того, що саме повинна робити система, то логічне проєктування
спрямоване на визначення того, з яких елементів вона складається та яким чином
ці елементи взаємодіють між собою. У межах логічної моделі визначаються
класи, їхні атрибути, операції, структури взаємозв’язків та організація
компонентів у пакети. Такий підхід дозволяє побудувати узгоджену архітектурну
основу, яка стане базою для подальшої реалізації системи. У цьому підпункті
наведено діаграми класів і пакетів, що відображають логічну структуру
розроблюваного веб-застосунку Movie Explorer.
3.2.3.1 Діаграми класів
Діаграма класів (рис. 3.4) відображає загальну структурну модель SPA-
додатку MovieExplorer та демонструє основні програмні сутності і зв’язки між
ними. Архітектура системи побудована за принципом поділу на рівень інтерфейсу
користувача, сервісний рівень та рівень моделей даних.
Рис. 3.4 – Загальна діаграма класів
57
ЧДТУ 252471.001 ПЗ
Описується пара сценаріїв використання, до яких можна додати діаграму
класів. Перший сценарій (рис. 3.5) охоплює логічну структуру компонентів та
сервісів Movie Explorer, що забезпечують перегляд списку фільмів, виконання
пошуку, зміну кількості відображуваних записів та відкриття детальної
інформації про вибраний фільм. Усі ці можливості формують єдиний модуль
роботи користувача з кінематографічним контентом, тому їх доцільно розглядати
в межах однієї діаграми класів. Основним елементом взаємодії є компонент
MovieListComponent, який відповідає за отримання, відображення та оновлення
списку фільмів. Компонент використовує MovieService для отримання даних із
відкритого API TMDB. Зв’язок між компонентом і сервісом є залежністю,
оскільки компонент викликає методи сервісу, не володіючи його екземпляром як
частиною своєї структури. Після вибору фільму зі списку користувач переходить
до компонента MovieDetailsComponent, який завантажує розширену інформацію
про вибраний фільм. Компонент також залежить від MovieService,
використовуючи метод отримання даних за ідентифікатором. Детальна
інформація представлена моделлю MovieDetails, яка містить ключові атрибути
фільму, але не включає підкласи жанрів — жанри можуть бути подані у вигляді
масиву рядків або опущені в цій моделі.
Таким чином, діаграма відображає повний цикл роботи користувача з
кінематографічними даними: від отримання списку фільмів до перегляду
детальної інформації про конкретний елемент. Структура діаграми демонструє
використання сервісу, моделі даних та логічні залежності між компонентами в
межах одного функціонального модуля.
У другому сценарії (рис. 3.6) моделюється механізм виконання
ресурсомісткої операції у двох режимах: безпосередньо в головному потоці
браузера та у фоновому потоці за допомогою Web Worker. Така функціональність
надає можливість порівняти вплив кожного із підходів на продуктивність
інтерфейсу та чітко продемонструвати переваги перенесення обчислень із
основного потоку. Центральним елементом сценарію є компонент
HeavyOperationComponent, який ініціює запуск операції та відображає її
58
ЧДТУ 252471.001 ПЗ
результат. У неоптимізованому режимі компонент виконує обчислення локально,
використовуючи вбудований метод виконання ітеративного алгоритму. У цьому
випадку вся логіка виконується в межах головного потоку, що призводить до
блокування UI на час виконання задачі. В оптимізованому режимі компонент
делегує обчислення фоновому потоку, використовуючи об’єкт WorkerWrapper.
Останній відповідає за створення Web Worker, обмін повідомленнями та
отримання результатів. Для передачі даних застосовуються структури
WorkerMessage та WorkerResult, що забезпечують уніфікований формат
комунікації між потоками.
Рис. 3.5 – Діаграма класів перегляду та пошуку фільмів
59
ЧДТУ 252471.001 ПЗ
Усі зв’язки між елементами мають характер залежностей, оскільки
компонент не володіє екземплярами воркера або допоміжних структур, а лише
використовує їх у процесі виконання операції. Сценарій демонструє архітектуру
оптимізації за допомогою розділення навантаження між потоками та формує
приклад практичного використання Web Worker у SPA-додатках.
Рис. 3.6 – Діаграма класів виконання важкої операції
3.2.3.2 Діаграма пакетів
У цьому підпункті представлено діаграму пакетів (рис. 3.7), що описує
логічну організацію модулів Movie Explorer. Діаграма пакетів дозволяє
сформувати узагальнене уявлення про структуру програмного комплексу,
виділити основні функціональні підсистеми та визначити залежності між ними.
Така форма моделювання є важливим етапом архітектурного проєктування,
оскільки надає можливість систематизувати компоненти та забезпечити логічний
поділ відповідальностей.
У контексті Movie Explorer система складається з декількох функціональних
областей: відображення списку фільмів, перегляд деталізованої інформації,
демонстраційні сценарії оптимізації та сценарії виконання важких обчислень
через Web Worker. Кожна з цих підсистем реалізована за допомогою окремих
компонентів, сервісів і моделей даних, які логічно згруповані у відповідні пакети.
60
ЧДТУ 252471.001 ПЗ
Рис. 3.7 – Діаграма пакетів
3.2.4 Архітектурне проектування
3.2.4.1 Діаграма компонентів
На діаграмі (рис. 3.8) представлена компонентна архітектура застосунку.
App Shell є ядром застосунку та містить базові елементи інтерфейсу, такі як
SideMenu, механізм маршрутизації та AppComponent, що забезпечує складання
сторінок.
Change Detection Feature містить компоненти для демонстрації роботи
механізму зміни стану: список фільмів, детальна інформація та тригер зміни
стану. Модуль активно взаємодіє з MovieService, який забезпечує доступ до API.
Web Worker Feature включає компонент WebWorkerComponent та окремий
скрипт worker.js, що виконує ресурсоємні операції поза основним потоком,
зменшуючи навантаження на UI та підвищуючи загальну продуктивність.
У блоці Shared Services розміщено спільні сервіси — MovieService для
взаємодії з TMDB API та PerformanceService для збору й аналізу метрик
61
ЧДТУ 252471.001 ПЗ
продуктивності. Саме вони забезпечують повторне використання логіки між
різними частинами системи.
Зовнішня взаємодія представлена компонентом External Service, що
моделює доступ до TMDB API.
Рис. 3.8 – Діаграма компонентів
3.2.4.2 Розгортання програмної системи на апаратних засобах. Діаграма
розгортання
У межах даного проєкту діаграма розгортання не будується, оскільки
62
ЧДТУ 252471.001 ПЗ
програмний продукт є клієнтським односторінковим веб-додатком, який
виконується локально на комп’ютері користувача та не передбачає складної
інфраструктури розгортання. Додаток не взаємодіє з власним серверним
програмним забезпеченням, не містить окремих вузлів обчислень або сервісів, що
потребували б моделювання фізичного розміщення компонентів у мережі.
Застосунок працює в межах браузерного середовища й використовує лише
зовнішній публічний API (TMDB), що не впливає на конфігурацію локальної
системи розгортання.
3.2.5 Моделювання поведінки системи
Моделювання поведінки системи дозволяє описати динамічні аспекти
роботи програмного забезпечення, зокрема послідовності дій, логіку прийняття
рішень та реакцію системи на дії користувача або зовнішні події. На відміну від
структурних моделей, які відображають статичну організацію компонентів,
поведінкові моделі демонструють зміну станів, потоки управління та основні
сценарії використання програмного комплексу. Для цього використовуються
діаграми діяльності, що дозволяють формально описати алгоритми
функціонування окремих частин системи та забезпечити чітке розуміння логіки
роботи додатка.
3.2.5.1 Діаграма діяльності
На діаграмі діяльності (рис. 3.9) зображено типовий сценарій взаємодії
користувача з програмою Movie Explorer під час пошуку та перегляду інформації
про фільм. Процес починається з відкриття додатку та введення пошукового
запиту. Далі виконується логічне розгалуження: якщо запит порожній, система
завантажує список популярних фільмів; у протилежному випадку — здійснюється
пошук за введеним ключем. Після формування списку користувач обирає
потрібний фільм, ініціюючи завантаження його детальної інформації.
Завершальним етапом є відображення сторінки з деталями фільму. Діаграма
демонструє основну логіку поведінки системи у межах ключового
функціонального сценарію.
63
ЧДТУ 252471.001 ПЗ
Рис. 3.9 – Діаграма діяльності перегляду і пошуку фільму
На діаграмі (рис. 3.10) зображено поведінку системи Movie Explorer під час
виконання важкої обчислювальної операції. Режим виконання визначається
системою автоматично на основі конфігурації додатку: у неоптимізованому
режимі операція виконується в головному потоці браузера, а в оптимізованому —
передається у Web Worker.
Після відкриття сторінки користувач ініціює виконання операції
натисканням кнопки. Залежно від активного режиму система або запускає
алгоритм безпосередньо в UI-потоці, або формує повідомлення для Web Worker,
очікує обробку та отримує результат з фонової задачі. У фіналі обчислення
64
ЧДТУ 252471.001 ПЗ
результат відображається користувачу незалежно від обраного способу
виконання.
Рис. 3.10 – Діаграма діяльності запуску важкої операції
3.2.5.2 Діаграма послідовності
На об’єднаній діаграмі послідовності (рис. 3.11) відображено дві
альтернативні моделі виконання важкої обчислювальної операції в Movie
Explorer, що залежать від конфігурації додатку. Після того як користувач ініціює
запуск операції, система визначає активний режим виконання: неоптимізований, у
65
ЧДТУ 252471.001 ПЗ
якому обчислення відбуваються безпосередньо в компоненті у головному потоці
браузера, або оптимізований, де виконання делегується Web Worker. У першому
варіанті компонент викликає власний метод обчислення та синхронно формує
результат, блокуючи UI під час роботи алгоритму. У другому варіанті компонент
передає параметри обчислення до WorkerWrapper, який надсилає повідомлення у
Web Worker. Worker виконує операцію у фоновому потоці та повертає результат
через зворотне повідомлення, після чого компонент оновлює інтерфейс без
блокування основного потоку.
Об’єднана діаграма демонструє ключові відмінності між двома підходами,
підкреслюючи ефективність використання Web Worker для підвищення
продуктивності SPA-додатків.
Рис. 3.11 – Діаграма послідовності обчислення важкої операції
66
ЧДТУ 252471.001 ПЗ
3.2.5.3 Діаграма комунікації
На діаграмі (рис. 3.12) представлено взаємодію основних учасників під час
тестування механізму Web Worker у додатку. Користувач ініціює виконання
важкого обчислення, натискаючи кнопку Start computation. Після цього
WebWorkerComponent створює екземпляр Web Worker та передає йому дані
задачі. Web Worker виконує обчислення в окремому потоці, що дозволяє
інтерфейсу залишатися відгукливим. Після завершення роботи Web Worker
повертає результат компоненту, який оновлює UI, а система відображає обчислені
дані користувачеві. Діаграма демонструє послідовність повідомлень та розподіл
відповідальності між компонентами при виконанні ресурсоємних операцій.
Рис. 3.12 – Діаграма комунікації виконання важкої операції
Друга діаграма комунікації (рис. 3.13) демонструє взаємодію компонентів
під час пошуку фільму та переходу до сторінки з його детальною інформацією.
Користувач вводить пошуковий запит, після чого MovieListComponent
звертається до MovieService, який надсилає запит до TMDB API. Отримані
результати виводяться на екран. Після вибору фільму відбувається навігація до
сторінки деталей, де MovieDetailsComponent отримує розширену інформацію про
фільм через MovieService і передає її інтерфейсу для відображення.
67
ЧДТУ 252471.001 ПЗ
Рис. 3.13 – Діаграма комунікації пошуку фільму
3.2.5.4 Діаграма скінченного автомату
Перша діаграма (рис. 3.14) демонструє логіку роботи інтерфейсу під час
пошуку фільму. У початковому стані Idle система очікує введення користувачем
та може відображати попередні результати. Під час введення запиту інтерфейс
переходить у стан Typing, з якого користувач може або підтвердити пошук, або
повернутися до початкового стану, очистивши поле. Після підтвердження запиту
система переходить у стан Loading, де здійснюється надсилання запиту до API та
відображення індикатора завантаження. Повернення результатів переводить
інтерфейс у стан Results, де користувачеві демонструється список знайдених
фільмів. Діаграма відображає основні переходи та внутрішні дії, характерні для
процесу пошуку.
68
ЧДТУ 252471.001 ПЗ
Рис. 3.14 – Діаграма скінченного автомату для пошуку фільму
Друга діаграма (рис. 3.15) описує процес виконання важких обчислень за
допомогою Web Worker. Початковий стан Idle відповідає очікуванню дій
користувача. Після запуску обчислень система переходить у стан Worker Init, де
створюється Web Worker. Далі відбувається перехід у стан Computing, де складна
операція виконується у фоновому потоці, не блокуючи основний інтерфейс. Після
завершення обчислень Worker повертає результат, і система переходить у стан
Completed, у якому оновлюється UI. Діаграма демонструє послідовність ключових
станів, що відображають роботу асинхронного механізму Web Worker.
69
ЧДТУ 252471.001 ПЗ
Рис. 3.15 – Діаграма скінченного автомату для обчислення важкої операції
70
ЧДТУ 252471.001 ПЗ
Висновки до розділу
У третьому розділі було здійснено комплексне моделювання та
архітектурне проєктування програмної системи Movie Explorer, що реалізує та
демонструє методи оптимізації продуктивності односторінкових веб-додатків
(SPA). На основі сформованої предметної області створено словник термінів,
визначено основні сутності, взаємозв’язки та сценарії взаємодії, що лягли в
основу побудови UML-моделей. Моделювання предметної області дало
можливість сформувати структурне бачення системи та чітко окреслити її
функціональні межі. У процесі формування та аналізу вимог було виділено
первинні (вимоги замовника) та детальні (вимоги розробника) специфікації, що
забезпечило поступовий перехід від концептуального опису до конкретної
функціональності, необхідної для реалізації SPA-додатку. Додатково сформовано
функціональні та нефункціональні вимоги, що визначають поведінку системи,
критерії її ефективності та обмеження, пов’язані з продуктивністю і
масштабованістю. Архітектурне проєктування передбачало побудову діаграм
класів, пакетів і поведінкових діаграм. Створені моделі відобразили логічну
структуру Movie Explorer, розподіл відповідальності між компонентами,
механізми взаємодії з зовнішніми сервісами та архітектурні рішення щодо
підтримки двох режимів роботи: оптимізованого та неоптимізованого.
Поведінкові діаграми (діяльності та послідовності) продемонстрували динамічні
аспекти роботи системи, включно з обробкою запитів, навігацією між сторінками
й виконанням важкої операції як у головному потоці, так і у Web Worker.
Узагальнюючи, розроблені моделі та архітектурні рішення стали практичним
відображенням результатів теоретичних і експериментальних досліджень,
виконаних у попередніх розділах. Вони забезпечили формалізацію логіки роботи
застосунку, дозволили структурувати систему відповідно до вимог
продуктивності та створили основу для реалізації та порівняння оптимізованої і
неоптимізованої версій SPA-додатку Movie Explorer.
71
ЧДТУ 252471.001 ПЗ
РОЗДІЛ 4. РОЗРОБКА ТА ТЕСТУВАННЯ ПРОГРАМНОГО
ЗАБЕЗПЕЧЕННЯ
4.1 Розробка програмного комплексу
4.1.1 Обґрунтування вибору засобів реалізації
Вибір мови програмування
Основною мовою реалізації було обрано TypeScript, що є надбудовою над
JavaScript та надає статичну типізацію, сучасні можливості ООП і глибоку
інтеграцію з Angular. Також з переваг TypeScript:
﹣ покращена підтримка IDE, яка знижує кількість помилок;
﹣ сумісність зі стандартами ECMAScript;
﹣ ефективна оптимізація під час збірки, яка прямо впливає на
продуктивність клієнтської частини.
Додатково використовувались HTML5 і SCSS для розробки інтерфейсу
користувача.
Вибір фреймворку
Для реалізації веб-додатка обрано Angular, оскільки цей фреймворк:
﹣ підтримує механізми оптимізації продуктивності, які є предметом
дослідження (ChangeDetectionStrategy, lazy loading, standalone
components, tree-shaking);
﹣ містить вбудовану архітектурну модель, що забезпечує структурованість
проєкту;
﹣ надає Angular CLI для швидкої генерації компонентів, модулів, сервісів,
конфігурацій збірки та оптимізованих збірок;
﹣ добре підходить для реалізації експериментального середовища, де
потрібно порівнювати оптимізовані та неоптимізовані варіанти одних і
тих самих сторінок.
Angular також забезпечує можливість реалізації web-worker потоків та
включає механізми компіляції, орієнтовані на продуктивність.
72
ЧДТУ 252471.001 ПЗ
Вибір інструменту керування потоками даних
Для роботи з асинхронними операціями в Angular використано бібліотеку
RxJS, яка є стандартом у реактивній розробці SPA. Її вибір обумовлений такими
перевагами:
﹣ ефективне керування асинхронністю: потокова модель дозволяє
обробляти HTTP-запити, події інтерфейсу та внутрішні зміни стану без
блокування основного потоку виконання;
﹣ оптимізація продуктивності: оператори debounceTime,
distinctUntilChanged, shareReplay та інші дозволяють зменшити кількість
непотрібних перерендерів та повторних запитів;
﹣ зменшення витрат пам’яті: використання операторів завершення
(takeUntil, finalize) дозволяє уникати витоків пам’яті;
﹣ інтеграція з Angular: підтримка async pipe забезпечує зручне й ефективне
оновлення UI без ручного управління підписками.
Завдяки цьому RxJS виступає ключовим інструментом для реалізації
реактивної логіки та оптимізації SPA, що відповідає завданням дослідження.
Вибір інструментів тестування та вимірювання продуктивності
Для аналізу продуктивності розробленого SPA-додатка були обрані
інструменти Google Lighthouse та вкладка Performance браузерних DevTools. Їх
використання обґрунтовується такими перевагами:
﹣ комплексність Lighthouse: інструмент виконує автоматизовану оцінку
ключових веб-метрик (LCP, FID, CLS, TTI, Speed Index), що дозволяє
об’єктивно порівнювати оптимізовані та неоптимізовані режими SPA;
﹣ реалістичні сценарії: Lighthouse моделює мережеві обмеження,
навантаження CPU та типові умови реального користувача,
забезпечуючи репрезентативність результатів;
﹣ аналітика низького рівня в Performance: вкладка Performance дає доступ
до детальних таймлайнів браузера, включно з розподілом часу на
scripting, rendering, painting, event loop та знайдення “довгих задач” (long
tasks);
73
ЧДТУ 252471.001 ПЗ
﹣ стандартизованість і доступність: обидва інструменти належать Chrome
DevTools, не потребують додаткового програмного забезпечення та є
загальновизнаним стандартом у галузі фронтенд-оптимізації.
Таким чином, використання Lighthouse і Performance забезпечує точні,
відтворювані та методично коректні вимірювання продуктивності SPA-додатка.
Вибір середовища розробки
Як основне середовище розробки використано Visual Studio Code —
кросплатформений редактор із широкою екосистемою розширень. Його переваги:
﹣ підтримка Angular та TypeScript через офіційні інструменти;
﹣ інтеграція з Git та вбудованим терміналом для роботи з Angular CLI;
﹣ висока продуктивність і низькі системні вимоги;
﹣ можливість швидкого налагодження та роботи в багатовіконному
режимі.
Таке середовище забезпечує зручний робочий процес, мінімізує часові
витрати та сприяє підвищенню якості коду.
Апаратне забезпечення
Розробка та тестування виконувалися на персональному комп’ютері з
конфігурацією:
﹣ macOS 15, ARM-процесор Apple M1;
﹣ 8 GB оперативної пам’яті;
﹣ SSD-накопичувач.
Дана конфігурація забезпечує швидку збірку Angular-додатків, стабільну
роботу емуляторів браузера та швидке виконання Lighthouse-аналізу.
4.1.2 Опис структурної (функціональної) схеми
Структурна та функціональна схеми програмного комплексу призначені для
відображення його внутрішньої організації та взаємодії основних компонентів.
Структурна схема показує склад підсистем і загальні зв’язки між ними.
Функціональна схема деталізує обмін даними між підсистемами, порядок
74
ЧДТУ 252471.001 ПЗ
виконання основних операцій та інформаційні потоки між програмним
забезпеченням, користувачем і зовнішніми ресурсами.
Рис. 4.1 – Структурна схема
Підсистема керування бібліотекою фільмів реалізує роботу з онлайн-
бібліотекою: завантаження списку фільмів, фільтрацію, пошук, перегляд
детальної інформації. Саме тут концентрується взаємодія з веб-сервісами
(REST/GraphQL API) та відображення контенту в інтерфейсі користувача.
Підсистема аналізу продуктивності та формування звітів відповідає за
перемикання режимів optimized / unoptimized, збирання та інтерпретацію метрик
(час завантаження, обсяг переданих даних, кількість запитів), а також за
формування підсумкових звітів для порівняння різних конфігурацій системи.
75
ЧДТУ 252471.001 ПЗ
Рис. 4.2 – Функціональна схема
Користувач задає параметри перегляду бібліотеки фільмів або параметри
експерименту через елементи інтерфейсу (блоки ручного введення).
Підсистема керування бібліотекою фільмів формує запити до публічного
API TMDB, отримує дані про фільми та передає їх на відображення у
користувацькому інтерфейсі.
Підсистема аналізу продуктивності та формування звітів виконує
вимірювання роботи додатка в різних режимах, отримує необхідні дані через той
самий зовнішній API та формує підсумковий звіт. Зовнішній API TMDB є єдиним
джерелом даних, а вихідними результатами роботи системи є відображення
списку/картки фільмів та сформований звіт про продуктивність.
76
ЧДТУ 252471.001 ПЗ
4.1.3 Опис логічної схеми системи
Рис. 4.3 – Діаграма діяльності процесу аналізу продуктивності
Алгоритм аналізу продуктивності:
﹣ користувач задає параметри тестування (вибір сторінки, режим
optimized/unoptimized);
﹣ система запускає процес вимірювання продуктивності;
﹣ в обраному режимі завантажується сторінка SPA;
﹣ Lighthouse / Performance збирають метрики (JS Heap, CPU Breakdown,
Long Tasks, Requests);
﹣ додатково компонент UI відображає внутрішні runtime-метрики:
﹣ кількість циклів Change Detection;
﹣ обсяг використаної памʼяті (Used JS Heap).
﹣ система показує результати користувачу.
77
ЧДТУ 252471.001 ПЗ
4.1.4 Розробка бази даних
У межах розробки SPA-додатку проєктування та реалізація власної бази
даних не здійснювались. Це обумовлено специфікою функціонального
призначення додатку та цілями дослідження. Movie Explorer є клієнтським
демонстраційним застосунком, основною задачею якого є аналіз і порівняння
методів оптимізації продуктивності в Single Page Applications, а не зберігання або
обробка власних користувацьких даних.
Усі необхідні дані та пов’язані метадані отримуються в режимі реального
часу з зовнішнього сервісу TMDB API. Таким чином, використання локальної або
серверної бази даних у межах проєкту є надлишковим і не впливає на досягнення
поставлених наукових і практичних цілей.
4.1.5 Розробка інтерфейсу користувача
Під час розробки інтерфейсу програмного комплексу за орієнтир були взяті
евристики usability Якоба Нільсена, що є загальновизнаними принципами
створення зручних і зрозумілих інтерфейсів.
У межах проєкту MovieExplorer було реалізовано ті евристики, які
безпосередньо стосуються функціональності та логіки роботи SPA, а саме:
Видимість стану системи
Інтерфейс чітко відображає поточний стан системи:
﹣ відображення ChangeDetection cycles та used memory (рис. 4.4);
﹣ індикатор завантаження під час виконання важкої операції (рис. 4.5).
Рис. 4.4 – Відображення метрик
78
ЧДТУ 252471.001 ПЗ
Рис. 4.5 – Індикатор завантаження
Відповідність реальному світу
Категорії, жанри, назви фільмів та структура подачі інформації
відповідають звичним моделям взаємодії користувачів із кінобібліотеками та
онлайн-каталогами (рис. 4.6).
Рис. 4.6 – Кінобібліотека
79
ЧДТУ 252471.001 ПЗ
Керованість та свобода дій
Користувач може легко:
﹣ повернутися до попереднього перегляду через кнопку «Back to list» (рис.
4.7);
﹣ коригувати параметри пошуку.
Рис. 4.7 – Кнопка для навігації
Послідовність та стандарти
Для інтерфейсу використано стандартні Angular-компоненти та PrimeNG,
що забезпечують:
﹣ узгоджені стилі;
﹣ передбачувану поведінку UI-елементів;
﹣ повторюваність інтерфейсних патернів у всьому застосунку.
Пізнавання замість пригадування
Інтерфейс мінімізує когнітивне навантаження:
﹣ навігаційне меню закріплено збоку й завжди доступне (рис. 4.8);
﹣ пошук містить плейсхолдер (рис. 4.9);
﹣ основні дії знаходяться у звичних місцях (зверху або зліва).
80
ЧДТУ 252471.001 ПЗ
Рис. 4.8 – Бокове меню
Рис. 4.9 – Плейсхолдер
81
ЧДТУ 252471.001 ПЗ
Естетичний та мінімалістичний дизайн
Інтерфейс побудований на темі Aura (PrimeNG) із дотриманням принципів
мінімалізму:
﹣ перевага чистого дизайну без зайвих деталей;
﹣ продумана палітра для темного режиму;
﹣ використання сучасної типографіки.
Гнучкість та ефективність використання
Архітектура SPA забезпечує:
﹣ можливість додавання нових сторінок або компонентів;
﹣ масштабування інтерфейсу в майбутньому без зміни базових UI-
патернів;
﹣ просте розширення режимів тестування продуктивності.
4.1.6 Опис розробки програмних компонентів
Розробка програмних компонентів SPA-додатку Movie Explorer
виконувалась із дотриманням принципів модульності та розділення
відповідальностей, що є характерними для Angular-застосунків на основі
NgModule. Архітектура додатку побудована на фреймворку Angular, який
забезпечує модульну організацію коду, механізм впровадження залежностей
(Dependency Injection) та компонентну модель побудови інтерфейсу. Додаток
розділено на функціональні модулі, що інкапсулюють пов’язані компоненти та
сервіси. Навігація між основними сторінками реалізована за допомогою Angular
Router, що забезпечує маршрутизацію без перезавантаження сторінки.
Компоненти представлення відповідають за формування користувацького
інтерфейсу, зокрема за відображення списків фільмів, детальної інформації та
елементів навігації. Для побудови UI використовується бібліотека PrimeNG, яка
надає готові візуальні компоненти та дозволяє зосередити увагу на логіці роботи
додатку й аналізі його продуктивності.
Бізнес-логіка та взаємодія із зовнішніми ресурсами реалізовані за
допомогою Angular-сервісів, які підключаються до модулів через механізм
82
ЧДТУ 252471.001 ПЗ
ін’єкції залежностей. Центральним елементом є сервіс взаємодії з TMDB API, що
відповідає за виконання HTTP-запитів і обробку отриманих даних. Для роботи з
асинхронними потоками використовується бібліотека RxJS, яка забезпечує
керування підписками та ефективну обробку подій.
Окремо виділено сервіси та компоненти, призначені для аналізу
продуктивності додатку. Вони забезпечують збір і відображення
експериментальних метрик, таких як кількість циклів change detection,
використання пам’яті та час виконання ресурсоємних операцій.
Важливою особливістю реалізації є підтримка двох режимів роботи —
оптимізованого та неоптимізованого. Перемикання між ними здійснюється на
рівні конфігурації середовища, що дає змогу змінювати підходи до реалізації
модулів і механізмів оптимізації без модифікації загальної архітектури додатку та
забезпечує коректність порівняльного аналізу.
4.2 Тестування системи
4.2.1 Модульне тестування
Модульне тестування є одним із базових підходів до забезпечення
надійності програмного забезпечення та передбачає перевірку окремих складових
системи в умовах їх ізоляції від інших компонентів. У межах даного виду
тестування оцінюється коректність реалізації функціональних можливостей
модулів, а також їхня здатність правильно реагувати на типові й граничні сценарії
використання. У межах розробленого односторінкового вебзастосунку модульне
тестування було зосереджене на клієнтській частині, зокрема на сервісах і
компонентах, що реалізують основну бізнес-логіку та механізми оптимізації
продуктивності. Для написання тестів використовувалися інструменти тестування
фреймворку Angular разом із бібліотекою Jasmine та середовищем виконання
Karma. Під час тестування застосовувалися мок-обʼєкти та шпигуни (spies), що
дало змогу ізолювати залежності та перевірити внутрішню логіку кожного модуля
незалежно від зовнішніх чинників. На рисунку 4.10 представлені результати
модульного тестування додатку, підсумки підбиті в таблиці 4.1.
83
ЧДТУ 252471.001 ПЗ
Рис. 4.10 – Результати модульного тестування
Таблиця 4.1
Підсумки модульного тестування
Модуль Тестована функція Очікуваний результат Результат
тесту
WebWorkersComp Виконання важких Коректне виконання Успішно
onent обчислень та обчислень з
перевірка відгуку використанням Web
інтерфейсу Worker або основного
потоку без блокування UI
84
ЧДТУ 252471.001 ПЗ
Продовження таблиці 4.1
MovieDetailsCompo Відображення та Дані фільму коректно Успішно
nent обробка завантажуються,
детальної обробляються та
інформації про навігація працює без
фільм помилок
AppComponent Ініціалізація Додаток успішно Успішно
кореневого ініціалізується та
компонента готовий до роботи
додатку
MovieCardCompone Відображення Компонент коректно Успішно
nt картки фільму та обробляє дані та
навігація до виконує перехід до
деталей сторінки деталей
PerformanceService Збір та обробка Метрики Успішно
метрик продуктивності
продуктивності коректно
обчислюються,
оновлюються та
скидаються без
помилок
TmdbService Отримання Дані з API успішно Успішно
даних з отримуються та
зовнішнього API обробляються у
(фільми, деталі, сервісі
пошук)
85
ЧДТУ 252471.001 ПЗ
4.2.2 Інтеграційне тестування
Інтеграційне тестування є важливим етапом перевірки програмної системи,
спрямованим на оцінку коректності взаємодії між окремими компонентами після
їхнього модульного тестування. На цьому етапі основна увага приділяється
перевірці того, чи правильно об’єднані модулі працюють у складі цілісного
застосунку, забезпечуючи коректний обмін даними та узгоджену логіку
виконання.
У межах розробленого односторінкового вебзастосунку інтеграційне
тестування було зосереджене на взаємодії між ключовими компонентами
клієнтської частини, а також на коректності роботи сервісів, що забезпечують
доступ до зовнішніх джерел даних. Перевірялися сценарії обміну даними між
компонентами інтерфейсу користувача та сервісним рівнем, зокрема отримання,
обробка та відображення даних, отриманих із зовнішнього API.
Особлива увага під час інтеграційного тестування приділялася перевірці
сценаріїв навігації, асинхронної обробки запитів та узгодженої роботи
компонентів у різних режимах оптимізації. Це дозволило переконатися, що
компоненти, які демонструють різні підходи до оптимізації продуктивності,
коректно взаємодіють між собою та не порушують загальну логіку роботи
застосунку.
Результати інтеграційного тестування підтвердили, що основні компоненти
системи успішно взаємодіють між собою відповідно до заданих вимог (таблиця
4.2). Обмін даними між компонентами здійснюється коректно, а застосунок
стабільно працює під час виконання типових користувацьких сценаріїв. Це
свідчить про готовність системи до подальшого використання та експлуатації в
реальних умовах.
Таблиця 4.2
Результати інтеграційного тестування
Компонент 1 Компонент 2 Очікуваний результат Результат тесту
86
ЧДТУ 252471.001 ПЗ
Продовження таблиці 4.2
Клієнтська Сервіс отримання Дані про фільми Успішно
частина (Angular даних (TmdbService) коректно
SPA) отримуються та
обробляються
Компонент Компонент картки Дані фільму коректно Успішно
списку фільмів фільму передаються та
(ChangeDetection (MovieCardComponent відображаються
Component) )
Компонент Маршрутизація Виконується Успішно
картки фільму (Angular Router) коректний перехід до
(MovieCardComp сторінки деталей
onent)
Компонент Сервіс отримання Детальна інформація Успішно
деталей фільму даних (TmdbService) про фільм успішно
(MovieDetailsCom завантажується
ponent)
Компонент Web Worker / Обчислення Успішно
важких головний потік виконуються без
обчислень блокування
(WebWorkersCom інтерфейсу
ponent)
Компоненти Сервіс збору метрик Метрики Успішно
інтерфейсу (PerformanceService) продуктивності
користувача коректно фіксуються
та оновлюються
4.2.3 Системне тестування
87
ЧДТУ 252471.001 ПЗ
Об’єктом системного тестування є односторінковий вебзастосунок
MovieExplorer, розглянутий як цілісний програмний комплекс. Метою тестування
було підтвердження відповідності системи функціональним вимогам, перевірка
коректності взаємодії із зовнішнім API TMDB, оцінка стабільності роботи
застосунку в умовах, наближених до реальних, а також аналіз продуктивності
системи в оптимізованому та неоптимізованому режимах виконання.
Системне тестування проводилося з використанням ручного тестування
основних користувацьких сценаріїв у поєднанні з інструментальним аналізом
продуктивності. Для оцінки показників швидкодії та завантаження ресурсів
застосовувався інструмент Lighthouse, а для детального аналізу виконання
JavaScript-коду, використання пам’яті та навантаження на процесор
використовувалися засоби Chrome DevTools, зокрема вкладка Performance. Такий
підхід дозволив комплексно оцінити поведінку системи як з точки зору
користувацького досвіду, так і з позиції ефективності використання ресурсів.
Програма системного тестування включала виконання таких основних
сценаріїв:
﹣ завантаження головної сторінки застосунку в оптимізованому та
неоптимізованому режимах;
﹣ виконання пошуку фільмів і перевірку коректності відображення
результатів;
﹣ перевірку переходів між сторінками та роботи маршрутизації;
﹣ аналіз відображення детальної інформації про вибраний фільм;
﹣ перевірку виконання ресурсоємних операцій із використанням Web
Worker;
﹣ аналіз показників продуктивності, зокрема використання пам’яті,
навантаження на процесор та наявності довгих задач;
﹣ перевірку відображення runtime-метрик, таких як кількість циклів change
detection і обсяг використаної пам’яті.
За результатами системного тестування (табл. 4.3) встановлено, що SPA
коректно функціонує в усіх перевірених сценаріях. Застосунок стабільно
взаємодіє із зовнішнім API, не демонструє критичних помилок під час виконання
основних операцій, а також забезпечує покращені показники продуктивності в
88
ЧДТУ 252471.001 ПЗ
оптимізованому режимі роботи. Отримані результати системного тестування
узгоджуються з експериментальними даними, наведеними в другому розділі
роботи, та підтверджують доцільність застосування запропонованих методів
оптимізації.
Таблиця 4.3
Результати системного тестування
Функція Очікуваний результат Результат тесту
Завантаження Головна сторінка коректно Успішно
головної сторінки завантажується в обох режимах
(optimized / unoptimized)
Пошук фільмів Фільми коректно знаходяться та Успішно
відображаються відповідно до запиту
Навігація між Перехід між сторінками здійснюється Успішно
сторінками без помилок і затримок
Перегляд деталей Детальна інформація про фільм Успішно
фільму коректно відображається
Виконання важкої Важка операція виконується без Успішно
операції блокування інтерфейсу
Робота з TMDB API Дані з зовнішнього API отримуються Успішно
та обробляються коректно
Аналіз Метрики продуктивності (JS Heap, Успішно
продуктивності CPU, long tasks) фіксуються коректно
4.2.4 Приймальне тестування
Основною метою приймального тестування було підтвердження коректної
роботи додатку як цілісної системи, а також перевірка готовності до експлуатації
89
ЧДТУ 252471.001 ПЗ
в умовах, наближених до реальних. Додатково була виконана перевірка стійкості
системи до типових несприятливих умов, зокрема тимчасової недоступності
зовнішнього API або затримок мережевих запитів. У таких випадках додаток
зберігав працездатність без критичних збоїв у роботі інтерфейсу.
У процесі приймального тестування також оцінювалась зручність взаємодії
користувача з інтерфейсом та відповідність поведінки додатку очікуваним
сценаріям використання. Перевірялась коректність навігації між сторінками,
зрозумілість елементів керування та стабільність відгуку інтерфейсу під час
виконання основних дій користувача.
Результати приймального тестування (табл. 4.4) показали, що всі основні
сценарії використання Movie Explorer виконуються коректно, а програмна
система відповідає заявленим функціональним і нефункціональним вимогам.
Додаток демонструє стабільну роботу, прогнозовану поведінку інтерфейсу та
наочну різницю між режимами виконання, що підтверджує можливість його
використання як демонстраційного та дослідницького програмного продукту.
Таблиця 4.4
Результати приймального тестування
Критерій Очікуваний результат Результат тесту
Зручність інтерфейсу Логічна навігація, інтуїтивно Успішно
зрозумілий інтерфейс
Функціональність Усі заявлені функції Успішно
працюють коректно
Продуктивність Час відгуку інтерфейсу не Успішно
перевищує 1 секунди
Стабільність роботи Відсутність критичних збоїв Успішно
під час роботи
90
ЧДТУ 252471.001 ПЗ
4.3 Приклади впровадженого програмного комплексу
Інструкція користувача
Під час запуску додаток може працювати у двох різних конфігураціях,
залежно від флагу:
﹣ unoptimized — традиційний модульний підхід;
﹣ optimized — Standalone Components + Lazy Loading + оптимізовані
механізми Change Detection.
Запуск здійснюється командою:
ng serve --configuration unoptimized
або
ng serve --configuration optimized
Бокове меню розташоване зліва та доступне на всіх сторінках.
Перехід між сторінками здійснюється одним кліком.
Меню містить такі розділи:
﹣ Dashboard;
﹣ Change Detection;
﹣ Web Workers.
Dashboard – це демонстраційна сторінка, метою якої є показ різниці в
рендерах між конфігураціями (рис. 4.10).
На сторінці знаходиться один статичний графік (chart) — він не виконує
реальних обчислень, але використовується для ілюстрації навантаження на DOM.
Користувач може переглянути сторінку. Спеціальної взаємодії немає.
Рис. 4.10 – Сторінка Dashboard
91
ЧДТУ 252471.001 ПЗ
Change Detection cторінка побудована для демонстрації роботи механізму
Change Detection та впливу на продуктивність (рис. 4.11).
Функціональність:
− кнопка “Increment Counter” при натисканні збільшує лічильник;
використовується для тригеру Change Detection і демонстрації
спрацьовувань CD-циклу в різних конфігураціях.
− список фільмів. Містить таблицю з даними, які можна фільтрувати.
Можливості: пошук за назвою; редагування кількості елементів на
сторінці; перехід на сторінку фільму; клік по будь-якому рядку
відкриває детальну сторінку обраного фільму (рис 4.12); на сторінці
відображається велика кількість інформації про фільм, що дозволяє
оцінити вплив об’єму DOM на продуктивність рендерингу.
Рис. 4.11 – Сторінка Change Detection
92
ЧДТУ 252471.001 ПЗ
Рис. 4.12 – Сторінка Movie Details
Web Workers сторінка створена для демонстрації розділення важких
обчислень між основним UI-потоком та Web Worker.
Функціональність:
﹣ кнопка “Start computation”:
﹣ запускає важку операцію (імітація великого обчислення);
﹣ якщо додаток працює в unoptimized конфігурації, UI може зависати;
﹣ якщо використовується Web Worker, UI залишається активним.
﹣ кнопка “Ping UI”. Використовується для тестування реактивності UI:
﹣ під час виконання важкої операції в головному потоці UI
відгукується із затримкою;
﹣ при роботі через Web Worker UI відповідає миттєво.
93
ЧДТУ 252471.001 ПЗ
Висновки до розділу
У четвертому розділі було здійснено перевірку якості та працездатності
розробленого SPA-додатку Movie Explorer шляхом проведення модульного,
інтеграційного та системного тестування. Отримані результати підтвердили
коректність реалізації основних функціональних сценаріїв, стабільну взаємодію з
зовнішнім API та передбачувану поведінку інтерфейсу в різних режимах роботи
застосунку.
У межах розділу також було створено структурну та логічну схеми
програмної системи, а також детально описано процес розробки її основних
програмних компонентів, що забезпечило цілісне уявлення про внутрішню
організацію та принципи побудови застосунку. Проведений аналіз продуктивності
засвідчив наявність помітної різниці між оптимізованою та не оптимізованою
конфігураціями, що підтверджує ефективність застосованих методів оптимізації
та готовність програмного забезпечення до практичного використання.
94
ЧДТУ 252471.001 ПЗ
ВИСНОВКИ
У роботі проведено комплексне теоретичне та експериментальне
дослідження методів оптимізації продуктивності веб-застосунків класу Single
Page Application (SPA) та їх практичної реалізації в сучасних інструментах веб-
розробки. Аналіз наукових і технічних джерел показав, що зростання складності
SPA, збільшення обсягів JavaScript-коду та підвищення вимог до інтерактивності
створюють суттєві виклики для забезпечення високої швидкодії. Це підкреслює
актуальність задачі оптимізації як важливої складової якості програмних
продуктів.
У роботі розв’язано наукову задачу підвищення продуктивності SPA
шляхом формалізації та застосування методів оптимізації різних класів, що
охоплюють параметричну, структурну, ресурсну та функціональну оптимізацію.
Наукова новизна полягає у формуванні комплексного підходу до вибору
оптимізаційних стратегій і розробленні методики порівняння ефективності цих
стратегій у реальних умовах роботи Angular-застосунків.
У ході дослідження застосовано та проаналізовано такі методи і об’єкти
оптимізації:
Структурний метод оптимізації
Структурні методи змінюють архітектуру, зв’язності та спосіб завантаження
частин системи. Об’єкти структурної оптимізації:
﹣ lazy loading. Завантаження модулів/сторінок тільки за потреби
(динамічні імпорти). Зменшує initial bundle і прискорює старт SPA;
﹣ code splitting. Автоматичне розбиття коду на чанки під час збірки
(Webpack / Angular CLI). Працює разом із Lazy Loading і зменшує
основний бандл;
﹣ resolvers. Механізм завантаження даних до активації маршруту.
Уникає «порожнього рендерингу», покращує UX і зменшує
навантаження на компонент.
Параметричний метод оптимізації
95
ЧДТУ 252471.001 ПЗ
Метод змінює параметри виконання Angular, не змінюючи структури
застосунку. Об’єкти параметричної оптимізації:
﹣ ChangeDetectionStrategy (Default / OnPush). Зменшує кількість циклів
перевірки стану. OnPush оптимізує роботу UI та знижує
навантаження на CPU;
﹣ *trackBy у ngFor. Уникає повторного створення DOM-елементів у
списках. Значно підвищує FPS та ефективність рендерингу.
Функціональний (алгоритмічний) метод оптимізації
Спрямований на оптимізацію алгоритмів обробки даних, компіляції та
виконання коду.
Об’єкти алгоритмічної оптимізації:
﹣ tree-shaking. Видаляє мертвий код на етапі збірки (Angular CLI + Ivy).
Зменшує розмір JavaScript-бандла;
﹣ RxJS оптимізація. Оптимальне керування підписками (takeUntil,
take(1), async pipe) — запобігає memory leaks. Дедублікація даних
(shareReplay) уникає дублювання HTTP-запитів, зменшує
навантаження. Контроль частоти подій (debounceTime) зменшує
кількість тригерів change detection та серверних викликів.
Ресурсний метод оптимізації
Має на меті оптимізувати використання CPU, памʼяті, мережі та головного
потоку. Об’єкт ресурсної оптимізації – Web Workers. Виконання важких
обчислень у фонових потоках поза основним UI [17].
Підвищує плавність інтерфейсу і скорочує блокування головного потоку.
Проведені експериментальні дослідження показали, що оптимізована
конфігурація SPA забезпечує суттєве підвищення продуктивності:
﹣ скорочення розміру початкового бандла;
﹣ зменшення часу виконання довгих задач;
﹣ покращення метрик FCP, LCP, INP та TTI до 20–45%;
﹣ зниження навантаження на JS Heap.
96
ЧДТУ 252471.001 ПЗ
що підтверджує дієвість запропонованих рішень. Надійність результатів
забезпечена повторними вимірюваннями, стандартизованою методикою
тестування та порівнянням із неоптимізованою базовою конфігурацією.
Практична цінність роботи полягає у створенні демонстраційного Angular-
застосунку, який може бути використаний для дослідження впливу
оптимізаційних стратегій у навчальних, наукових та реальних промислових
системах. Розроблені підходи можуть бути інтегровані в існуючі веб-продукти
для підвищення ефективності, стійкості та масштабованості.
Перспективи подальшого розвитку дослідження полягають у:
﹣ інтеграції хмарних сервісів (AWS, GCP, Azure, Cloudflare) для
віддаленого збору та аналізу продуктивності;
﹣ адаптації оптимізаційних методів для мобільних платформ та
прогресивних вебзастосунків (PWA);
﹣ розширенні аналізу за рахунок Edge Rendering та SSR.
97
ЧДТУ 252471.001 ПЗ
СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ
1 Angular Documentation – Change Detection – [Електронний ресурс] – Режим
доступу: https://angular.io/guide/change-detection
2 Angular Docs – Standalone Components – [Електронний ресурс] – Режим
доступу: https://angular.io/guide/standalone-components
3 Angular Docs – Lazy Loading Feature Modules – [Електронний ресурс] –
Режим доступу: https://angular.io/guide/lazy-loading-ngmodules
4 Angular Performance Best Practices – [Електронний ресурс] – Режим доступу:
https://angular.dev/best-practices/runtime-performance
5 RxJS Documentation – [Електронний ресурс] – Режим доступу:
https://rxjs.dev/guide/overview
6 Web Workers API – MDN – [Електронний ресурс] – Режим доступу:
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API
7 Tree-shaking in JavaScript – MDN – [Електронний ресурс] – Режим доступу:
https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking
8 Lighthouse Performance Scoring – [Електронний ресурс] – Режим доступу:
https://developer.chrome.com/docs/lighthouse/performance
9 Single Page Application (SPA) – MDN – [Електронний ресурс] – Режим
доступу: https://developer.mozilla.org/en-US/docs/Glossary/SPA
10 Модель предметної області – [Електронний ресурс] – Режим доступу:
https://uk.wikipedia.org/wiki/Модель_предметної_області
11 Діаграма прецедентів – [Електронний ресурс] – Режим доступу:
https://uk.wikipedia.org/wiki/Діаграма_прецедентів
98
ЧДТУ 252471.001 ПЗ
12 TMDB API Documentation – [Електронний ресурс] – Режим доступу:
https://developer.themoviedb.org/reference/intro/getting-started
13 Chrome DevTools – Performance Panel – [Електронний ресурс] – Режим
доступу: https://developer.chrome.com/docs/devtools/performance
14 Web Vitals – Core Metrics (FCP, LCP, TTI, CLS) – [Електронний ресурс] –
Режим доступу: https://web.dev/vitals/
15 W3C Web Performance Working Group – [Електронний ресурс] – Режим
доступу: https://www.w3.org/webperf/
16 Браузерна оптимізація – MDN – [Електронний ресурс] – Режим доступу:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules
17 Preload & Resource Priorities – [Електронний ресурс] – Режим доступу:
https://developer.chrome.com/blog/link-rel-preload
18 Caching Best Practices – HTTP Caching – MDN – [Електронний ресурс] –
Режим доступу: https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching
19 Системне тестування - [Електронний ресурс] - Режим доступу:
https://uk.wikipedia.org/wiki/Системне_тестування
99
ДОДАТОК А
ЗАТВЕРДЖЕНО:
Зав. кафедри ПЗАС
проф. Голуб С. В.
___________________________
ОПТИМІЗАЦІЯ ПРОДУКТИВНОСТІ ПРОГРАМ В SINGLE PAGE
APPLICATIONS
Специфікація
482.ЧДТУ.252471 01
Листів 2
Розробник ________________ Андрющенко Д.А.
Керівник ________________ Немченко В.В.
Черкаси 2025
482.ЧДТУ.252471 01 2
Позначення Найменування Примітка
482.ЧДТУ.252471 12-01 Лістинг програми
482.ЧДТУ.252471 90-01 Графічні матеріали
101
ДОДАТОК Б
ОПТИМІЗАЦІЯ ПРОДУКТИВНОСТІ ПРОГРАМ В SINGLE PAGE
APPLICATIONS
Лістинг програми
482.ЧДТУ.252471 12-01
Листів 35
Розробник ________________ Андрющенко Д.А.
Черкаси 2025
482.ЧДТУ.252471 12-01 2
Файл main.ts
import 'zone.js';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.optimized) {
const preload = document.createElement('link');
preload.rel = 'preload';
preload.as = 'style';
preload.href =
'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap';
document.head.appendChild(preload);
const stylesheet = document.createElement('link');
stylesheet.rel = 'stylesheet';
stylesheet.href = preload.href;
stylesheet.media = 'print';
stylesheet.onload = () => stylesheet.media = 'all';
document.head.appendChild(stylesheet);
const connect1 = document.createElement('link');
connect1.rel = 'preconnect';
connect1.href = 'https://fonts.googleapis.com';
document.head.appendChild(connect1);
const connect2 = document.createElement('link');
connect2.rel = 'preconnect';
connect2.href = 'https://fonts.gstatic.com';
connect2.crossOrigin = '';
document.head.appendChild(connect2);
}
platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.error(err));
Файл index.html
<!doctype html>
<html lang="en">
103
482.ЧДТУ.252471 12-01 3
<head>
<meta charset="utf-8">
<title>MovieExplorer</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
Файл app.ts
import { AfterViewInit, Component, inject, OnInit } from '@angular/core';
import { Router, RouterOutlet } from '@angular/router';
import { PerformanceService } from './core/services/performance.service';
import { RenderTracker } from './core/utils/render-tracker.directive';
@Component({
standalone: false,
selector: 'app-root',
templateUrl: './app.html',
styleUrls: ['./app.scss']
})
export class AppComponent extends RenderTracker implements OnInit, AfterViewInit {
private router = inject(Router);
ngOnInit() {
if (this.router.url === '/' || this.router.url === '') {
this.router.navigate(['/change-detection']);
}
}
ngAfterViewInit() {
this.perf.markFirstRender();
}
104
482.ЧДТУ.252471 12-01 4
}
Файл app.html
<router-outlet></router-outlet>
Файл app.routes.unoptimized.ts
import { Routes } from "@angular/router";
import { SideMenuComponent } from "./components/side-menu/side-menu.component";
import { DashboardComponent } from "./pages/dashboard/dashboard.component";
import { ChangeDetectionComponent } from "./pages/change-detection/change-detection.component";
import { MovieDetailsComponent } from "./pages/movie-details/movie-details.component";
import { WebWorkersComponent } from "./pages/web-workers/web-workers.component";
export const routes: Routes = [
{
path: '',
component: SideMenuComponent,
children: [
{
path: 'dashboard',
component: DashboardComponent
},
{
path: 'change-detection',
component: ChangeDetectionComponent
},
{
path: 'change-detection/movie/:id',
component: MovieDetailsComponent
},
{
path: 'web-workers',
component: WebWorkersComponent
},
105
482.ЧДТУ.252471 12-01 5
{ path: '', redirectTo: 'change-detection', pathMatch: 'full' }
]
}
];
Файл app.routes.optimized.ts
import { Routes } from '@angular/router';
import { SideMenuComponent } from './components/side-menu/side-menu.component';
export const routes: Routes = [
{
path: '',
component: SideMenuComponent,
children: [
{
path: 'dashboard',
loadChildren: () =>
import('./pages/dashboard/dashboard.module').then(m => m.DashboardModule)
},
{
path: 'change-detection',
loadChildren: () =>
import('./pages/change-detection/change-detection.module').then(m =>
m.ChangeDetectionModule)
},
{
path: 'web-workers',
loadChildren: () =>
import('./pages/web-workers/web-workers.module').then(m => m.WebWorkersModule)
},
{ path: '', redirectTo: 'change-detection', pathMatch: 'full' }
]
}
];
106
482.ЧДТУ.252471 12-01 6
Файл app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, RouterOutlet } from '@angular/router';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { SideMenuComponent } from './components/side-menu/side-menu.component';
import { routes } from './app.routes';
import { cacheInterceptor } from './core/interceptors/cache-interceptor';
import { AppComponent } from './app';
import { CommonModule } from '@angular/common';
import { ButtonModule } from 'primeng/button';
import { TagModule } from 'primeng/tag';
import { CdCounterComponent } from './components/cd-counter/cd-counter.component';
import { environment } from '../environments/environment';
import { DashboardModule } from './pages/dashboard/dashboard.module';
import { ChangeDetectionModule } from './pages/change-detection/change-detection.module';
import { WebWorkersModule } from './pages/web-workers/web-workers.module';
import { providePrimeNG } from 'primeng/config';
import Aura from '@primeuix/themes/aura';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
@NgModule({
declarations: [
AppComponent,
SideMenuComponent
],
imports: [
RouterOutlet,
BrowserModule,
RouterModule.forRoot(routes, { initialNavigation: 'enabledBlocking' }),
CommonModule,
ButtonModule,
107
482.ЧДТУ.252471 12-01 7
TagModule,
CdCounterComponent,
...(environment.optimized ? [] : [
DashboardModule,
ChangeDetectionModule,
WebWorkersModule
])
],
providers: [
provideHttpClient(withInterceptors([cacheInterceptor])),
providePrimeNG({
theme: {
preset: Aura
},
}),
provideAnimationsAsync(),
],
bootstrap: [AppComponent]
})
export class AppModule {}
Файл cd-counter.component.ts
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, NgZone, OnDestroy, OnInit,
inject } from '@angular/core';
import { PerformanceService } from '../../core/services/performance.service';
import { TagModule } from 'primeng/tag';
import { ButtonModule } from 'primeng/button';
@Component({
selector: 'app-cd-counter',
standalone: true,
imports: [TagModule, ButtonModule],
templateUrl: './cd-counter.component.html',
styleUrls: ['./cd-counter.component.scss'],
108
482.ЧДТУ.252471 12-01 8
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CdCounterComponent implements OnInit, OnDestroy {
private perf = inject(PerformanceService);
private cdr = inject(ChangeDetectorRef);
private zone = inject(NgZone);
private timerId: any;
cdCount = 0;
metrics = this.perf.metrics;
ngOnInit(): void {
this.zone.runOutsideAngular(() => {
this.timerId = setInterval(() => {
const newCd = this.perf.cdCount;
const newMetrics = this.perf.metrics;
if (
newCd !== this.cdCount ||
newMetrics.memoryUsedMb !== this.metrics.memoryUsedMb ||
newMetrics.ttfrMs !== this.metrics.ttfrMs
) {
this.cdCount = newCd;
this.metrics = { ...newMetrics };
this.zone.run(() => this.cdr.detectChanges());
}
}, 500);
});
}
ngOnDestroy(): void {
if (this.timerId) clearInterval(this.timerId);
}
reset() {
this.perf.reset();
this.cdCount = 0;
this.metrics = { ttfrMs: null, memoryUsedMb: null };
this.cdr.detectChanges();
109
482.ЧДТУ.252471 12-01 9
}
}
Файл cd-counter.component.html
<div class="metrics-container">
<p-tag severity="info" [value]="'CD: ' + cdCount"></p-tag>
<p-tag severity="success" [value]="'TTFR: ' + (metrics.ttfrMs ?? '-') + ' ms'"></p-tag>
<p-tag severity="warn" [value]="'Memory: ' + (metrics.memoryUsedMb ?? '-') + ' MB'"></p-tag>
<button pButton style="margin-top: 1.5rem" type="button" label="Reset Metrics" icon="pi pi-
trash" (click)="reset()"></button>
</div>
Файл cd-counter.component.scss
.metrics-container {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
Файл movie-card.component.ts
import { Component, Input, ChangeDetectionStrategy, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { CardModule } from 'primeng/card';
import { TagModule } from 'primeng/tag';
import { environment } from '../../../environments/environment';
import { Router } from '@angular/router';
import { RenderTracker } from '../../core/utils/render-tracker.directive';
@Component({
selector: 'app-movie-card',
standalone: false,
templateUrl: './movie-card.component.html',
styleUrls: ['./movie-card.component.scss'],
changeDetection: environment.optimized ? ChangeDetectionStrategy.OnPush :
ChangeDetectionStrategy.Default
110
482.ЧДТУ.252471 12-01 10
})
export class MovieCardComponent extends RenderTracker {
private router = inject(Router);
@Input() movie: any;
@Input() optimized = false;
navigateToDetails() {
this.router.navigate(['/change-detection/movie', this.movie.id]);
}
}
Файл movie-card.component.ts
<p-card class="movie-card" (click)="navigateToDetails()">
<ng-template pTemplate="header">
<img
[src]="'https://image.tmdb.org/t/p/w500' + movie.poster_path"
[alt]="movie.title"
[loading]="optimized ? 'lazy' : null"
/>
</ng-template>
<div class="movie-info">
<h3>{{ movie.title }}</h3>
<p>{{ movie.release_date | date }}</p>
<p-tag value="{{ movie.vote_average }}" severity="info"></p-tag>
</div>
</p-card>
Файл movie-card.component.scss
.movie-card {
text-align: center;
cursor: pointer;
img {
width: 100%;
border-radius: var(--border-radius);
}
111
482.ЧДТУ.252471 12-01 11
}
Файл movie-list.component.ts
import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
import { CommonModule } from '@angular/common';
import { CardModule } from 'primeng/card';
import { DividerModule } from 'primeng/divider';
import { MovieCardComponent } from '../movie-card/movie-card.component';
import { environment } from '../../../environments/environment';
import { RenderTracker } from '../../core/utils/render-tracker.directive';
@Component({
selector: 'app-movie-list',
standalone: false,
templateUrl: './movie-list.component.html',
styleUrls: ['./movie-list.component.scss'],
changeDetection: environment.optimized ? ChangeDetectionStrategy.OnPush :
ChangeDetectionStrategy.Default
})
export class MovieListComponent extends RenderTracker {
@Input() movies: any[] | null = null;
@Input() optimized = false;
trackMovie = (index: number, movie: any) =>
this.optimized ? movie.id : index;
}
Файл movie-list.component.html
<div class="movie-list">
@if (movies && movies.length > 0) {
@for (movie of movies; track trackMovie($index, movie)) {
<app-movie-card [movie]="movie" [optimized]="optimized"></app-movie-card>
}
} @else {
<p>No movies loaded.</p>
112
482.ЧДТУ.252471 12-01 12
}
</div>
Файл movie-list.component.scss
.movie-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 1rem;
}
Файл side-menu.component.ts
import { Component } from '@angular/core';
import { RenderTracker } from '../../core/utils/render-tracker.directive';
@Component({
selector: 'app-side-menu',
standalone: false,
templateUrl: './side-menu.component.html',
styleUrls: ['./side-menu.component.scss'],
})
export class SideMenuComponent extends RenderTracker {}
Файл side-menu.component.html
<div class="layout">
<aside class="side-nav">
<div class="menu-links">
<button
pButton
label="Dashboard"
icon="pi pi-home"
routerLink="/dashboard"
routerLinkActive="p-button-outlined"
class="p-button-text w-full text-left"
></button>
113
482.ЧДТУ.252471 12-01 13
<button
pButton
label="Change Detection"
icon="pi pi-sync"
routerLink="/change-detection"
routerLinkActive="p-button-outlined"
class="p-button-text w-full text-left"
></button>
<button
pButton
label="Web Workers"
icon="pi pi-cloud-download"
routerLink="/web-workers"
routerLinkActive="p-button-outlined"
class="p-button-text w-full text-left"
></button>
</div>
<div style="margin-top: auto;">
<app-cd-counter></app-cd-counter>
</div>
</aside>
<main class="content">
<router-outlet></router-outlet>
</main>
</div>
Файл side-menu.component.scss
:host {
display: block;
height: 100vh;
font-family: var(--font-family);
}
.layout {
display: flex;
114
482.ЧДТУ.252471 12-01 14
height: 100%;
width: 100%;
}
.side-nav {
width: 240px;
background: var(--surface-section);
border-right: 1px solid var(--surface-border);
padding: 1rem;
box-sizing: border-box;
flex-shrink: 0;
display: flex;
flex-direction: column;
}
.menu-title {
color: var(--primary-color);
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 1rem;
}
.menu-links {
display: flex;
flex-direction: column;
gap: 0.5rem;
margin-top: 1.5rem;
}
.content {
flex: 1;
padding: 1.5rem;
overflow-y: auto;
background: var(--surface-ground);
}
Файл cache-interceptor.ts
import { HttpEvent, HttpInterceptorFn, HttpRequest, HttpHandlerFn } from '@angular/common/http';
115
482.ЧДТУ.252471 12-01 15
import { Observable, of, tap } from 'rxjs';
import { environment } from '../../../environments/environment';
const responseCache = new Map<string, HttpEvent<unknown>>();
export const cacheInterceptor: HttpInterceptorFn = (
req: HttpRequest<unknown>,
next: HttpHandlerFn
): Observable<HttpEvent<unknown>> => {
if (req.method !== 'GET') {
return next(req);
}
if (!environment.optimized) {
const noCacheReq = req.clone({
setParams: { t: Date.now().toString() } // Bypass cache by adding a timestamp
});
return next(noCacheReq);
}
const cached = responseCache.get(req.urlWithParams);
if (cached) {
return of(cached);
}
return next(req).pipe(
tap(event => {
responseCache.set(req.urlWithParams, event);
})
);
};
Файл movie-details.resolver.ts
import { inject } from '@angular/core';
import { ResolveFn } from '@angular/router';
import { forkJoin } from 'rxjs';
import { TmdbService } from '../services/tmdb.service';
116
482.ЧДТУ.252471 12-01 16
export const movieDetailsResolver: ResolveFn<any> = (route) => {
const tmdb = inject(TmdbService);
const id = Number(route.paramMap.get('id'));
return forkJoin({
details: tmdb.getMovieDetails(id),
credits: tmdb.getMovieCredits(id),
videos: tmdb.getMovieVideos(id),
recommendations: tmdb.getMovieRecommendations(id),
reviews: tmdb.getMovieReviews(id),
});
};
Файл tmdb.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '../../../environments/environment';
import { forkJoin, map, Observable } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class TmdbService {
private apiUrl = environment.apiUrl;
private apiKey = environment.apiKey;
constructor(private http: HttpClient) {}
getPopularMovies(limit: number = 20) {
const moviesPerPage = 20;
const pages = Math.ceil(limit / moviesPerPage);
const requests = Array.from({ length: pages }, (_, i) =>
this.http.get<any>(`${this.apiUrl}/movie/popular?api_key=${this.apiKey}&page=${i + 1}`)
);
return forkJoin(requests).pipe(
map(responses => responses.flatMap(r => r.results).slice(0, limit))
);
}
117
482.ЧДТУ.252471 12-01 17
getMovieDetails(id: number): Observable<any> {
return this.http.get(`${this.apiUrl}/movie/${id}?api_key=${this.apiKey}&language=en-US`);
}
getMovieCredits(id: number): Observable<any> {
return this.http.get(`${this.apiUrl}/movie/${id}/credits?api_key=${this.apiKey}&language=en-
US`);
}
getMovieVideos(id: number): Observable<any> {
return this.http.get(`${this.apiUrl}/movie/${id}/videos?api_key=${this.apiKey}&language=en-
US`);
}
getMovieRecommendations(id: number): Observable<any> {
return
this.http.get(`${this.apiUrl}/movie/${id}/recommendations?api_key=${this.apiKey}&language=en-
US`);
}
getMovieReviews(id: number): Observable<any> {
return this.http.get(`${this.apiUrl}/movie/${id}/reviews?api_key=${this.apiKey}&language=en-
US`);
}
searchMovies(query: string): Observable<any[]> {
return
this.http.get(`${this.apiUrl}/search/movie?api_key=${this.apiKey}&query=${encodeURIComponent(
query)}`).pipe(
map((response: any) => response.results)
);
}
}
Файл performance.service.ts
import { Injectable, NgZone } from '@angular/core';
export interface AppPerformanceMetrics {
ttfrMs: number | null;
memoryUsedMb: number | null;
118
482.ЧДТУ.252471 12-01 18
}
@Injectable({ providedIn: 'root' })
export class PerformanceService {
private ttfrMarked = false;
cdCount = 0;
metrics: AppPerformanceMetrics = {
ttfrMs: null,
memoryUsedMb: null,
};
constructor(private zone: NgZone) {
if ((performance as any).memory) {
this.zone.runOutsideAngular(() => {
setInterval(() => this.updateMemoryUsage(), 2000);
});
}
}
markFirstRender() {
if (this.ttfrMarked) return;
this.ttfrMarked = true;
const navTiming = performance.getEntriesByType('navigation')[0] as
PerformanceNavigationTiming | undefined;
const ttfr = navTiming
? navTiming.responseEnd - navTiming.startTime
: performance.now();
this.metrics.ttfrMs = Math.round(ttfr);
}
incrementChangeDetection() {
this.cdCount++;
}
reset() {
this.cdCount = 0;
this.metrics.ttfrMs = null;
119
482.ЧДТУ.252471 12-01 19
this.metrics.memoryUsedMb = null;
this.ttfrMarked = false;
}
private updateMemoryUsage() {
const perfAny = performance as any;
if (!perfAny.memory) return;
const usedBytes = perfAny.memory.usedJSHeapSize as number;
const usedMb = usedBytes / (1024 * 1024);
this.metrics.memoryUsedMb = Math.round(usedMb * 10) / 10;
}
}
Файл render-tracker.directive.ts
import { AfterViewChecked, Directive, inject } from '@angular/core';
import { PerformanceService } from '../services/performance.service';
@Directive()
export class RenderTracker implements AfterViewChecked {
protected perf = inject(PerformanceService);
ngAfterViewChecked() {
this.perf.incrementChangeDetection();
}
}
Файл change-detection.component.ts
import { Component, ChangeDetectionStrategy, OnDestroy, inject, OnInit, ChangeDetectorRef } from
'@angular/core';
import { environment } from '../../../environments/environment';
import { debounceTime, Observable, shareReplay, Subject } from 'rxjs';
import { TmdbService } from '../../core/services/tmdb.service';
@Component({
selector: 'app-change-detection',
120
482.ЧДТУ.252471 12-01 20
standalone: false,
templateUrl: './change-detection.component.html',
styleUrls: ['./change-detection.component.scss'],
changeDetection: environment.optimized ? ChangeDetectionStrategy.OnPush :
ChangeDetectionStrategy.Default
})
export class ChangeDetectionComponent implements OnInit, OnDestroy {
private tmdbService = inject(TmdbService);
private cdr = inject(ChangeDetectorRef);
optimized = environment.optimized;
counter = 0;
movies$?: Observable<any[]>;
movies: any[] = [];
search$ = new Subject<string>();
constructor() {
this.onLimitChange();
}
ngOnInit() {
this.search$.pipe(debounceTime(400)).subscribe(searchValue => {
console.log('Searching for:', searchValue);
this.movies$ = this.tmdbService.searchMovies(searchValue);
this.cdr.detectChanges();
});
}
increment() {
this.counter++;
}
onLimitChange(limit: number = 20) {
if (this.optimized) {
this.movies$ = this.tmdbService.getPopularMovies(limit).pipe(shareReplay(1));
} else {
this.tmdbService.getPopularMovies(limit).subscribe({
next: res => {
121
482.ЧДТУ.252471 12-01 21
this.movies = res;
this.cdr.detectChanges();
},
});
}
}
onSearchChange(searchValue: string) {
if (this.optimized) {
this.search$.next(searchValue);
} else {
this.tmdbService.searchMovies(searchValue).subscribe({
next: res => {
this.movies = res;
this.cdr.detectChanges();
},
});
}
}
ngOnDestroy() {
if (this.optimized) {
this.search$.complete();
this.search$.unsubscribe();
}
}
}
Файл change-detection.component.html
<h2>Change Detection Demo</h2>
<div class="header">
<button pButton label="Increment Counter" (click)="increment()"></button>
<p>Counter: {{ counter }}</p>
<div class="limit-select">
<p-select
[options]="[20, 100, 300, 700, 1000]"
122
482.ЧДТУ.252471 12-01 22
class="w-12rem"
(onChange)="onLimitChange($event.value)">
</p-select>
</div>
<div class="search-box">
<input
pInputText
placeholder="Search movies..."
(input)="onSearchChange($event.target.value)"
class="w-20rem"
/>
</div>
</div>
@if (optimized) {
<app-movie-list
[movies]="movies$ | async"
[optimized]="optimized">
</app-movie-list>
} @else {
<app-movie-list
[movies]="movies"
[optimized]="optimized">
</app-movie-list>
}
Файл change-detection.component.scss
.header {
margin-bottom: 1.5rem;
display: flex;
align-items: center;
gap: 1rem;
flex-wrap: wrap;
}
.limit-select {
123
482.ЧДТУ.252471 12-01 23
display: flex;
align-items: center;
gap: 0.5rem;
margin-left: auto;
background: var(--surface-section);
padding: 0.5rem 1rem;
border-radius: var(--border-radius);
box-shadow: var(--card-shadow);
}
.limit-select label {
font-weight: 500;
color: var(--text-color-secondary);
}
.limit-select p-select {
min-width: 10rem;
}
.search-box {
display: flex;
align-items: center;
background: var(--surface-section);
padding: 0.5rem 1rem;
border-radius: var(--border-radius);
box-shadow: var(--card-shadow);
input {
width: 100%;
}
}
Файл dashboard.component.ts
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { RenderTracker } from '../../core/utils/render-tracker.directive';
@Component({
selector: 'app-dashboard',
124
482.ЧДТУ.252471 12-01 24
standalone: false,
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DashboardComponent extends RenderTracker {
chartData = {
labels: ['Change Detection', 'Resolvers', 'Web Workers', 'Cache'],
datasets: [
{
label: 'Optimization Impact (relative)',
data: [80, 60, 70, 50],
},
],
};
chartOptions = {
maintainAspectRatio: false,
};
}
Файл dashboard.component.html
<div class="p-card" style="padding: 2rem;">
<h2 class="text-xl font-semibold" style="margin-top: 0;">Optimization Overview</h2>
<p class="text-color-secondary mb-4">
Example chart using PrimeNG Charts to visualize relative impact of different optimization
techniques.
</p>
<div>
<p-chart type="bar" [data]="chartData" [options]="chartOptions"></p-chart>
</div>
</div>
Файл movie-details.component.ts
125
482.ЧДТУ.252471 12-01 25
import { Component, ChangeDetectionStrategy, ChangeDetectorRef, OnInit, inject } from
'@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { environment } from '../../../environments/environment';
import { TmdbService } from '../../core/services/tmdb.service';
import { forkJoin } from 'rxjs';
import { DomSanitizer } from '@angular/platform-browser';
import { RenderTracker } from '../../core/utils/render-tracker.directive';
@Component({
selector: 'app-movie-details',
standalone: false,
templateUrl: './movie-details.component.html',
styleUrls: ['./movie-details.component.scss'],
changeDetection: environment.optimized ? ChangeDetectionStrategy.OnPush :
ChangeDetectionStrategy.Default,
})
export class MovieDetailsComponent extends RenderTracker implements OnInit {
private route = inject(ActivatedRoute);
private router = inject(Router);
private tmdbService = inject(TmdbService);
private cdr = inject(ChangeDetectorRef);
private sanitizer = inject(DomSanitizer);
optimized = environment.optimized;
data: any = null;
ngOnInit() {
if (this.optimized) {
this.data = this.route.snapshot.data['movie'];
this.sanitizeVideoUrls();
} else {
const id = Number(this.route.snapshot.paramMap.get('id'));
forkJoin({
details: this.tmdbService.getMovieDetails(id),
credits: this.tmdbService.getMovieCredits(id),
126
482.ЧДТУ.252471 12-01 26
videos: this.tmdbService.getMovieVideos(id),
recommendations: this.tmdbService.getMovieRecommendations(id),
reviews: this.tmdbService.getMovieReviews(id),
}).subscribe(res => {
this.data = res;
this.sanitizeVideoUrls();
this.cdr.detectChanges();
});
}
}
private sanitizeVideoUrls() {
if (this.data?.videos?.results) {
this.data.videos.results = this.data.videos.results.map((video: any) => ({
...video,
safeUrl: this.sanitizer.bypassSecurityTrustResourceUrl(
`https://www.youtube.com/embed/${video.key}`
),
}));
}
}
goBack() {
this.router.navigate(['/change-detection']);
}
}
Файл movie-details.component.html
@if (data) {
<button
pButton
label="Back to list"
icon="pi pi-arrow-left"
class="p-button-outlined back-button"
(click)="goBack()"
></button>
127
482.ЧДТУ.252471 12-01 27
<div class="movie-header">
<img [src]="'https://image.tmdb.org/t/p/w500' + data.details.poster_path" alt="Poster" />
<div class="info">
<h1>{{ data.details.title }}</h1>
<p><strong>Release date:</strong> {{ data.details.release_date }}</p>
<p><strong>Rating:</strong> {{ data.details.vote_average }}</p>
<p class="overview">{{ data.details.overview }}</p>
</div>
</div>
<h2>Cast</h2>
<div class="cast">
@for (actor of data.credits.cast.slice(0, 8); track actor.id) {
<div class="actor">
<img [src]="'https://image.tmdb.org/t/p/w200' + actor.profile_path" alt="{{ actor.name }}" />
<p>{{ actor.name }}</p>
</div>
}
</div>
<h2>Trailers</h2>
<div class="videos">
@for (video of data.videos.results.slice(0, 2); track video.id) {
<iframe
width="420"
height="235"
[src]="video.safeUrl"
frameborder="0"
allowfullscreen
></iframe>
}
</div>
<h2>Reviews</h2>
<div class="reviews">
@for (review of data.reviews.results.slice(0, 3); track review.id) {
128
482.ЧДТУ.252471 12-01 28
<div class="review"> <strong>{{ review.author }}</strong>
<p>{{ review.content }}</p>
</div>
}
</div>
<h2>Recommendations</h2>
<div class="recommendations">
@for (rec of data.recommendations.results.slice(0, 6); track rec.id) {
<div class="rec">
<img [src]="'https://image.tmdb.org/t/p/w200' + rec.poster_path" alt="{{ rec.title }}" />
<p>{{ rec.title }}</p>
</div>
}
</div>
} @else {
<p>Loading movie details...</p>
}
Файл movie-details.component.scss
.movie-header {
display: flex;
gap: 1rem;
img {
width: 200px;
border-radius: 8px;
}
.info {
flex: 1;
}
}
.cast, .recommendations {
display: flex;
flex-wrap: wrap;
gap: 1rem;
129
482.ЧДТУ.252471 12-01 29
.actor, .rec {
width: 120px;
text-align: center;
}
img {
border-radius: 8px;
width: 100%;
}
}
.videos {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.reviews {
.review {
margin-bottom: 1rem;
background: var(--surface-section);
padding: 1rem;
border-radius: 8px;
}
}
.back-button {
margin-bottom: 1rem;
background: none;
border: none;
color: var(--primary-color, #3f51b5);
font-size: 1rem;
cursor: pointer;
font-weight: 500;
transition: color 0.2s ease;
&:hover {
color: var(--primary-700, #2c387e);
text-decoration: underline;
130
482.ЧДТУ.252471 12-01 30
}
}
Файл web-workers.component.ts
import { Component, ChangeDetectionStrategy, ChangeDetectorRef, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { environment } from '../../../environments/environment';
import { ButtonModule } from 'primeng/button';
import { ProgressSpinnerModule } from 'primeng/progressspinner';
import { MessageModule } from 'primeng/message';
import { CardModule } from 'primeng/card';
import { SelectModule } from 'primeng/select';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { RenderTracker } from '../../core/utils/render-tracker.directive';
@Component({
selector: 'app-web-workers',
standalone: false,
templateUrl: './web-workers.component.html',
styleUrls: ['./web-workers.component.scss'],
changeDetection: environment.optimized
? ChangeDetectionStrategy.OnPush
: ChangeDetectionStrategy.Default,
})
export class WebWorkersComponent extends RenderTracker {
private cdr = inject(ChangeDetectorRef);
optimized = environment.optimized;
running = false;
result: string | null = null;
options = [
{ label: 'Option 1', value: 1 },
{ label: 'Option 2', value: 2 },
{ label: 'Option 3', value: 3 }
];
131
482.ЧДТУ.252471 12-01 31
selectControl = new FormControl<number | null>(null);
pingUI() {
console.log('UI responsive — Ping!', this.selectControl.value);
}
startComputation() {
this.running = true;
this.result = null;
const start = performance.now();
if (this.optimized) {
const worker = new Worker(
new URL('./heavy-task.worker', import.meta.url),
{ type: 'module' }
);
worker.postMessage({ limit: 10_000_000 });
worker.onmessage = ({ data }) => {
const time = (performance.now() - start).toFixed(0);
this.result = `Completed in ${time} ms (via Web Worker). Found ${data.count} primes (last =
${data.last}).`;
this.running = false;
worker.terminate();
this.cdr.detectChanges();
};
} else {
const result = this.calculatePrimes(10_000_000);
const time = (performance.now() - start).toFixed(0);
this.result = `Completed in ${time} ms (Main Thread). Found ${result.count} primes (last =
${result.last}).`;
this.running = false;
}
}
private calculatePrimes(limit: number) {
const primes: number[] = [];
for (let i = 2; i < limit; i++) {
132
482.ЧДТУ.252471 12-01 32
let isPrime = true;
for (let j = 2; j * j <= i; j++) {
if (i % j === 0) {
isPrime = false;
break;
}
}
if (isPrime) primes.push(i);
}
return { count: primes.length, last: primes.at(-1) };
}
}
Файл web-workers.component.html
<div class="p-card web-workers-demo p-4">
<h2 class="text-primary text-xl font-semibold mb-2">Web Workers Demo</h2>
<p>
Demonstrates how heavy computations affect the UI in
<strong>
{{ optimized ? 'Optimized (Web Worker)' : 'Unoptimized (Main Thread)' }}
</strong>
mode.
</p>
<div class="flex justify-content-center mb-4">
<p-button
label="Start Computation"
icon="pi pi-play"
[loading]="running"
(onClick)="startComputation()"
[disabled]="running"
></p-button>
</div>
<p>Try interacting with UI while computation runs</p>
<div class="ping-container">
133
482.ЧДТУ.252471 12-01 33
<p-button
label="Ping UI"
icon="pi pi-bolt"
(onClick)="pingUI()"
[disabled]="false"
></p-button>
<p-select
[options]="options"
[formControl]="selectControl"
placeholder="Select an option"
></p-select>
</div>
@if (running) {
<div class="spinner-container">
<p-progressSpinner
class="w-4rem h-4rem"
strokeWidth="4"
fill="transparent"
animationDuration=".8s"
></p-progressSpinner>
<p class="text-color-secondary">Processing...</p>
</div>
}
@if (result) {
<p-message
[severity]="optimized ? 'success' : 'warn'"
[text]="result"
class="mt-4"
></p-message>
}
</div>
Файл web-workers.component.scss
.web-workers-demo {
max-width: 600px
134
482.ЧДТУ.252471 12-01 34
margin: 3rem auto;
padding: 2rem;
h2 {
color: var(--primary-color);
}
.p-message {
text-align: left;
white-space: pre-line;
}
.p-card {
background: var(--surface-card);
box-shadow: var(--card-shadow);
border-radius: var(--border-radius);
}
}
.ping-container {
display: flex;
gap: 1rem;
margin-bottom: 1rem;
}
.spinner-container {
display: flex;
flex-direction: column;
align-items: center;
}
Файл heavy-task.worker.ts
addEventListener('message', ({ data }) => {
const result = calculatePrimes(data.limit);
postMessage(result);
});
function calculatePrimes(limit: number) {
const primes: number[] = [];
for (let i = 2; i < limit; i++) {
135
482.ЧДТУ.252471 12-01 35
let isPrime = true;
for (let j = 2; j * j <= i; j++) {
if (i % j === 0) {
isPrime = false;
break;
}
}
if (isPrime) primes.push(i);
}
return { count: primes.length, last: primes.at(-1) };
}
136
ДОДАТОК В
ОПТИМІЗАЦІЯ ПРОДУКТИВНОСТІ ПРОГРАМ В SINGLE PAGE
APPLICATIONS
Графічні матеріали
482.ЧДТУ.252471 90-01
Листів 16
Розробник ________________ Андрющенко Д.А.
Черкаси 2025
482.ЧДТУ.252471 90-01 2
Рисунок В.1 – Слайд 1
Рисунок Г.2 – Слайд 2
138
482.ЧДТУ.252471 90-01 3
Рисунок Г.3 – Слайд 3
Рисунок Г.4 – Слайд 4
139
482.ЧДТУ.252471 90-01 4
Рисунок Г.5 – Слайд 5
Рисунок Г.6 – Слайд 6
140
482.ЧДТУ.252471 90-01 5
Рисунок Г.7 – Слайд 7
Рисунок Г.8 – Слайд 8
141
482.ЧДТУ.252471 90-01 6
Рисунок Г.9 – Слайд 9
Рисунок Г.10 – Слайд 10
142
482.ЧДТУ.252471 90-01 7
Рисунок Г.11 – Слайд 11
Рисунок Г.12 – Слайд 12
143
482.ЧДТУ.252471 90-01 8
Рисунок Г.13 – Слайд 13
Рисунок Г.14 – Слайд 14
144
482.ЧДТУ.252471 90-01 9
Рисунок Г.14 – Слайд 15
Рисунок Г.16 – Слайд 16
145
482.ЧДТУ.252471 90-01 10
Рисунок Г.17 – Слайд 17
Рисунок Г.18 – Слайд 1
146
482.ЧДТУ.252471 90-01 11
Рисунок Г.19 – Слайд 19
Рисунок Г.20 – Слайд 20
147
482.ЧДТУ.252471 90-01 12
Рисунок Г.21 – Слайд 21
Рисунок Г.22 – Слайд 22
148
482.ЧДТУ.252471 90-01 13
Рисунок Г.23 – Слайд 23
Рисунок Г.24 – Слайд 24
149
482.ЧДТУ.252471 90-01 14
Рисунок Г.25 – Слайд 25
Рисунок Г.26 – Слайд 26
150
482.ЧДТУ.252471 90-01 15
Рисунок Г.27 – Слайд 27
Рисунок Г.28 – Слайд 28
151
482.ЧДТУ.252471 90-01 16
Рисунок Г.29 – Слайд 29
Рисунок Г.30 – Слайд 30
152