Модуль 3 · урок 10 з 11
Профайлінг
Оптимізація без вимірювання — це вгадування. Цей короткий урок про те, як побачити change detection на власні очі: скільки вузлів перевіряється, скільки це коштує в мілісекундах і що показати ліду замість слів «я поставив OnPush».
Angular DevTools
Розширення для Chrome від команди Angular. Дає дві речі, яких немає у звичайних DevTools:
- Components — дерево компонентів із їхніми input, output і поточним станом. Зручно, коли треба зрозуміти, що саме прилетіло в дитину.
- Profiler — запис циклів перевірки: скільки їх було, які компоненти в них потрапили й скільки часу зайняв кожен.
Як читати профайлер
- Натисни запис, зроби дію в застосунку — наприклад, поводи мишею над таблицею.
- Зупини запис. Побачиш стовпчики: кожен — один цикл перевірки.
- Клікни на стовпчик — знизу підсвітиться дерево з часом на кожен компонент.
Головне, на що дивитись: скільки компонентів підсвічено. До OnPush там буде
все дерево, після — кілька вузлів. Це і є той доказ, який має сенс показувати.
Найпереконливіший сценарій: відкрити екран із таблицею, записати профайл під час руху миші,
показати, що циклів багато, а перевірених компонентів у кожному — одиниці. І одразу поруч —
той самий запис із тимчасово вимкненим OnPush для порівняння. Різниця
у стовпчиках говорить сама.
Швидкий вимір без розширення
// у консолі браузера, у дев-збірці
ng.profiler.timeChangeDetection();
// Ran 425 change detection cycles in 1002ms; 2.36ms per check
Дає одне число: скільки коштує один повний цикл перевірки. Орієнтир простий — якщо це число перевищує кілька мілісекунд, інтерфейс уже відчувається вʼязким, бо в секунду таких циклів можуть бути десятки.
Звичайні DevTools теж стають у пригоді
| Інструмент | Що показує |
|---|---|
| Performance | Довгі задачі в головному потоці: видно, чи це рендер, чи твоя логіка |
| Rendering → Paint flashing | Підсвічує ділянки, які браузер перемальовує. Якщо блимає весь екран замість одного рядка — проблема саме тут |
| Memory → Heap snapshot | Знімок до й після переходу між екранами: якщо памʼять не звільняється, десь лишилась підписка (модуль 4) |
Порядок дій, коли «щось гальмує»
- Виміряти. Профайлер або
timeChangeDetection— спершу цифра, потім гіпотези. - Порахувати вузли. Скільки компонентів у циклі? Якщо все дерево — бракує
OnPushдесь угорі. - Пошукати роботу в шаблоні. Виклики методів, фільтрація в
@for, нечисті пайпи — усе це виконується щоразу. - Перевірити
track. Якщо список перебудовується цілком, DOM-операції зʼїдять більше, ніж сама перевірка. - Аж потім думати про віртуальний скрол. Тисяча рядків у DOM — це дорого незалежно від change detection; але спершу варто виправити перші чотири пункти.
OnPushна всіх компонентах.- Незмінні оновлення й
trackу циклах. computedзамість методів у шаблоні.@deferдля важких блоків нижче видимої зони.
detach()«щоб не перевірялось».- Ручні
detectChanges()по всьому коду. - Заміна бібліотеки таблиці без вимірювання.
- Оптимізація того, що й так виконується раз на завантаження екрана.
«Я виміряв профайлером: до OnPush у кожному циклі перевірялось усе дерево,
після — три компоненти. Виклики методів із шаблону замінив на computed,
у списку додав track по id, тож при зміні одного рядка перемальовується
саме він.»