vyvchy
    Теми розділу

    10 · Performance testing

    Performance-тести в CI/CD

    Зміст

    Перф-тест поза — це подія: раз на квартал команда виділяє тиждень, знімає числа й пише звіт. продуктивності приїжджає не раз на квартал, а з кожним : додали зайвий запит у циклі, підняли залежність, увімкнули ще один сторонній скрипт. Між подією і мерджем — три місяці, за які причину вже не відновити, бо змін накопичилося двісті.

    Звідси й тема глави: як перетворити перф-тестування з події на властивість процесу. Це рівень сеньйора не тому, що тут складна механіка, а тому, що ціна помилки лежить не в тесті, а в довірі: гейт, який моргає червоним без причини, вимикають, — і канон SRE називає цей результат прямо. Далі — що ставити гейтом, на якому рівні запускати і з чим порівнювати. Як улаштований сам пайплайн — стадії, , тригери, артефакти, секрети — розбирає розділ про Git і CI/CD: будова пайплайна і стратегія якості в пайплайні.

    Що перф-тест робить у пайплайні — і чого не робить

    Канон ISTQB відповідає одним реченням: у безперервній інтеграції головна мета перф-тестів — переконатися, що зміна не погіршила продуктивність. Це інше питання, ніж те, на яке відповідає повноцінний навантажувальний прогін: там ми шукаємо межу системи, тут — різницю між «до» і «після». Звідси й обмеження, з якого починається весь дизайн: через короткий час, доступний у CI, тести в пайплайні можуть бути підмножиною ширших тестів, які в інший час ганяє спеціалізована команда. Ця сама вимога робить перф-роботу ранньою: канон наполягає, щоб аналіз починався рано й повторювався регулярно, а не зводився до одного прогону наприкінці системного тестування.

    Друга половина рамки — застереження від протилежної крайності. Дока k6 формулює її без пом'якшень: автоматизація часто означає прогін із pass/fail у CI/CD, однак не всі перф-тести придатні для CI/CD- й не зводяться до статусу «зелено/червоно» та ролі воротаря релізу. Більше того, запуск тестів тільки з CI на зміни коду обмежує цілі перф-тестування. Альтернативи названі поіменно: cron і cron-, ручний запуск як пункт релізного чекліста. Мета всієї конструкції там само сформульована як зміна режиму роботи: продуктивність у багатьох організаціях лишається невідчутною, і на неї реагують, лише коли стається погане, — автоматизація переводить команду з реактивного режиму в проактивний.

    Практичний висновок для дизайну: пайплайн не має бути єдиним місцем, звідки стартують перф-тести. У ньому живе швидка підмножина, решта — за розкладом і руками.

    Перф-смоук на PR: найдешевший рівень

    у перф-контексті — це не «маленький load-тест», а перевірка, що прогін узагалі має сенс. Дока k6 радить починати саме з нього: перед більшими прогонами валідувати, що скрипт працює як очікується і що система нормально почувається під мінімальним навантаженням. Параметри задані там само: низьке навантаження, тривалість у секундах або хвилинах, привід — зміна відповідного системного чи застосункового коду, а перевіряє він функціональну логіку, базові метрики й відхилення.

    Зверніть увагу на привід: «зміна відповідного коду» — це буквально опис тригера PR. Тому смоук і є природним мешканцем цього рівня. Він коштує хвилини, вписується в час джоби й ловить найдорожчий клас поломок — зламаний сценарій. Скрипт, який після переїзду збирає 404 замість замовлень, у нічному прогоні виявиться о шостій ранку, коли три години генератора вже витрачено; на PR він виявиться за дві хвилини.

    Друга роль смоуку — тримати свіжим (performance baseline), тобто набір метрик для порівняння поточних і раніше досягнутих вимірів. Канон окремо каже, що базовий вимір може бути потрібно спершу створити, використовуючи знеособлені дані з бази, — тобто це підготовлений артефакт, а не зріз проду, і саме тому він відтворюваний. Без нього фактичні результати прогону неможливо оцінити: без набору базових вимірів, що визначають прийнятну й неприйнятну продуктивність, «700 мс» лишається числом без вердикту. Сам вид тесту й склад знімка розбирає глава про види перф-тестів.

    Поріг як гейт релізу, а не як вердикт прогону

    Поріг (threshold) як критерій pass/fail самого прогону — предмет глави про вимоги до продуктивності. Тут питання інше: чи має цей вердикт когось зупиняти.

    Технічно міст між прогоном і пайплайном вузький до непристойності. Якщо всі пороги виконано, інструмент виходить із кодом 0; якщо провалено хоч один — з ненульовим. Це весь інтерфейс: решта — звіти, дашборди, гарні графіки — призначена людям, а не гейту. Звідси перше правило: перф-джоба без порогів гейтом не є ніколи, скільки б артефактів вона не лишала. Те саме стосується чеків: невдалі чеки не переривають тест і не завершують його зі статусом провалу, інструмент лише веде облік їхньої частки, — щоб чек щось блокував, його треба поєднати з порогом. А саме число береться не з інструмента, а з , які канон вимагає прив'язувати до цілей перф-тесту, SLA і базових значень.

    Тепер найцікавіше — форма гейта. Найближчий задокументований аналог у нашій індустрії — гейт на коду, і Google називає розвилки поіменно: гейт на все проти гейта лише на новий код; гейт на жорстко задане число проти гейта на дельту від попередньої версії. Друга розвилка для продуктивності і є головною. Абсолютний поріг («p(95) оформлення нижчий за 500 мс») перевіряє вимогу й не залежить від історії, але на слабкому CI-середовищі він або постійно червоний, або настільки послаблений, що не ловить нічого. Дельта від базового виміру («не гірше ніж на 10% проти попереднього релізу») ловить саме регресію, але мовчить, коли система повільна вже давно. Робочий гейт зазвичай тримає обидва критерії. названий у тому самому джерелі: гейт може вистрілити у зворотний бік, якщо перетвориться на чекбокс, бо «тиск влучити в метрику майже ніколи не дає бажаного результату» — а найпростіший спосіб «влучити» у перф-метрику — послабити поріг, і зроблено це буде о другій ночі перед релізом.

    І дві механічні пастки, через які фраза «у нас усе під гейтом» частіше за все неправдива. Обов'язкова перевірка вважається пройденою, якщо вона в стані successful, skipped або neutral, — тобто перф-джоба, яку пропустила умова if у самій джобі, лишає гейт зеленим і нікого не турбує. А зелений CI взагалі не є апрувом: у формулюванні доки зміни лише «готові до рецензії або злиття». Локальна перевірка гейтом не є за побудовою: pre-commit обходиться опцією --no-verify, тож хук дає швидкий фідбек, а не блокує. Сам напрямок руху перевірок канон CTFL називає прямо: CI просуває shift-left, підштовхуючи віддавати код разом із компонентними тестами й , — перф-смоук у цю логіку вкладається природно. Механіку захищених гілок розбирає стратегія якості в пайплайні.

    Порівняння з базовим виміром: що з чим і за якою метрикою

    Найважливіше твердження глави канон SRE формулює в темі , і воно переноситься на перф-гейт один в один: оскільки час є одним із найбільших джерел зміни спостережуваних метрик, оцінити деградацію продуктивності порівнянням «до й після» важко. Механізм простий: деградацію міг спричинити , а могла вона статися й у контрольній системі теж. Канонічний приклад — реліз у понеділок означає порівняння поведінки в робочий день із поведінкою у вихідні, «вносячи великий обсяг шуму».

    Наслідок для CI прямий: «прогін сьогодні проти прогону тижневої давнини» — слабкий доказ регресії. Сильніші дві конструкції. Перша — серія прогонів на одному : вона показує власну дисперсію вимірів, тобто ту саму різницю, яку ви інакше приписали б зміні. Друга — паралельний контрольний прогін: обидві версії міряються в тому самому часі й у тих самих умовах. Канон і тут застерігає: контроль та кандидат часто ділять бекенди, мережу й сховище, а спільний домен псує обидві сторони порівняння.

    Питання: чи стало гірше?

    Прогін сьогодні проти прогону тижневої давнини

    Серія прогонів на одному коміті

    Паралельний контрольний прогін

    Час — джерело зміни метрик:
    шум не відділити від регресії

    Видно власну дисперсію вимірів

    Обидві версії в тих самих умовах

    Питання: чи стало гірше?

    Прогін сьогодні проти прогону тижневої давнини

    Серія прогонів на одному коміті

    Паралельний контрольний прогін

    Час — джерело зміни метрик:
    шум не відділити від регресії

    Видно власну дисперсію вимірів

    Обидві версії в тих самих умовах

    Розкид при цьому лікують повтореннями, а не ширшим порогом. Lighthouse CI прямо тримає в переліку своїх можливостей ганяти аудит багато разів, щоб зменшити дисперсію, — це канонічне визнання того, що одиничний перф-вимір шумний, і механічна відповідь на шум — повторення, а не послаблення критерію.

    Друге питання — за якою метрикою порівнювати. Канон відповідає й на нього: найкращі метрики — коди відповіді HTTP і відповіді, бо їх деградація найточніше відповідає реальній проблемі, що впливає на користувачів; натомість метрики використання процесора не такі корисні — зростання витрат ресурсу не обов'язково впливає на сервіс і може дати нестабільний, шумний процес. Далі йде наслідок, який пояснює смерть половини перф-гейтів: шумний процес оператори можуть вимкнути або почати ігнорувати, а це знецінює саму ідею. Число теж назване: беріть кілька найкращих метрик, можливо, не більш ніж дюжину, бо забагато метрик дають спадну віддачу, а з певного моменту вигоду перекриває вартість підтримки або втрата довіри до релізного процесу. Коди 4xx при цьому з оцінки виключають, додавши перевірку наявності конкретного URL: 404 може означати і зламаний сервер, і просто те, що користувачі йдуть за неправильним посиланням. Над усім цим стоїть одна вимога — джерело змін у спостережуваних метриках має бути чітко віднесене до зміни, яку ми перевіряємо, і не мусить залежати від зовнішніх чинників; саме тому гейт ставлять не на «процесор системи», а на час процесора, витрачений на обслуговування запиту.

    Оцінювати сам гейт зручно словником, який канон дає в темі сповіщень: точність (частка спрацювань, які були значущими), повнота (частка значущих подій, які виявлено), час виявлення і час скидання — причому довгий час скидання призводить до плутанини або до ігнорування проблем. Там же названа й межа однопорогового правила, і названа числом: швидкість витрачання 35 не спрацьовує ніколи, хоча з'їдає весь місячний за 20,5 години. Мораль для CI: один поріг завжди має сліпу зону, і саме тому рівнів запуску більше ніж один.

    Рівні запуску: PR-смоук, нічний load, релізний повний

    Канон дає готову модель рівнів — знову ж таки в темі канарки: замість оцінювати один етап, використовують кілька, що відображають нашу здатність міркувати про метрики. На малому етапі перевагу надають метрикам, які найясніше вказують на проблему, — падінням застосунку, відмовам запитів, — а тонші метрики стають придатними лише на більшій вибірці. Перекладіть це на пайплайн — і рівні запуску вибудовуються самі.

    Ні

    Так

    Пуш у PR

    Перф-смоук: кілька користувачів, хвилини
    грубі ознаки: відмови запитів, зламаний сценарій

    Пороги виконано?

    PR блокується

    Мердж

    Нічний прогін за розкладом:
    повний профіль навантаження, тонкі метрики

    Історія результатів і тренд

    Релізний прогін:
    повний набір + порівняння з базовим виміром

    Ні

    Так

    Пуш у PR

    Перф-смоук: кілька користувачів, хвилини
    грубі ознаки: відмови запитів, зламаний сценарій

    Пороги виконано?

    PR блокується

    Мердж

    Нічний прогін за розкладом:
    повний профіль навантаження, тонкі метрики

    Історія результатів і тренд

    Релізний прогін:
    повний набір + порівняння з базовим виміром

    Механіка розділення на диво проста: шлях до скриптів у дії запуску задається шаблоном, тобто різні шаблони дають різні набори тестів із того самого репозиторію. Ще одна деталь того самого джерела варта уваги — підготовка середовища й власне прогін рознесені на дві різні дії, тож у джобі видно, що саме впало: не встановився інструмент чи не пройшов тест. Це рівно та різниця, яку «зелено/червоно» приховує.

    Розкладка по рівнях у типовому проєкті виглядає так:

    type PerfLevel = {
      trigger: 'pull_request' | 'schedule' | 'release';
      scriptGlob: string;      // './tests/smoke*.ts' | './tests/load*.ts'
      duration: string;        // 'хвилини' | 'десятки хвилин' | 'години'
      gate: 'blocking' | 'report-only';
      compareWith: 'none' | 'baseline' | 'previous-release';
    };

    Ключове поле тут gate — і саме його значення канон не приписує. Він дає модель етапів: кілька замість одного, на малому етапі перевагу мають найгрубіші метрики, тонші стають придатними лише на більшій вибірці. Який з етапів блокує мердж, який лише звітує, а який має право зупинити реліз — рішення проєкту, а не вимога стандарту, і залежить воно від апетиту команди до ризику. Те, що частина перф-тестів у CI не поміщається взагалі, дока k6 каже прямо, називаючи cron і ручний запуск як штатні альтернативи.

    Шум спільного ранера

    Почнемо з того, що документоване. Специфікації hosted-ранерів GitHub залежать від видимості репозиторію: станом на 2026-08-01 та сама мітка ubuntu-latest дає 4 процесори й 16 ГБ у публічному репозиторії й 2 процесори та 8 ГБ у приватному. з суфіксом -latest — це останні стабільні образи, які можуть не бути найсвіжішою версією ОС від постачальника, тобто мітка версію не закріплює. Що саме виконувало джобу, видно в логах прогону — і це єдине надійне джерело відповіді на питання «чому вчора було швидше». Так само не закріплена й версія самого інструмента: дія встановлення k6 бере останню версію, якщо версію не задано явно, тож стрибок цифр може бути наслідком оновлення, а не змін у системі.

    Тепер про сусідів. Канон SRE описує цей клас точно, хоч і не про CI: у великій популяції машин ймовірні викиди — перевантажені (oversubscribed) машини, машини з іншими ядрами й іншими характеристиками продуктивності або машини в перевантаженому сегменті мережі. І дає вердикт, який прямо переноситься на спільний ранер: сильно поруч із нашим процесом — очевидна проблема, але вона не спричинена зміною, яку ми перевіряємо, тож не має позначатися як провал. Рецепт той самий, що вище: обирати метрику, віднесену до самої роботи, — не загальне використання процесора системою, а час процесора, витрачений на обслуговування запиту.

    Наша практика (не канон). Далі — те, як це роблять команди, з якими ми працювали; окремого стандарту чи специфікації під це немає. Абсолютні числа зі спільного ранера між прогонами не порівнюють: ранер тримають пусковим механізмом, а не вимірювальним приладом. Навантаження генерують у виділене середовище, а гейт на PR лишають грубим — відмови запитів, явно зламаний сценарій, кратне погіршення, — тоді як тонке порівняння з базовим виміром роблять на виділеному залізі й на нічному рівні. У звіт джоби корисно класти рядок про те, який ранер виконував прогін: без нього розслідування «чому в четвер було вдвічі повільніше» починається з нуля. І чесна межа: скільки саме повторів достатньо і який розкид вважати «однаковими прогонами» — числа не дає жодне джерело, яке ми перевіряли. Канон каже лише «повторюйте, щоб зменшити дисперсію»; конкретний команда встановлює сама, за власними вимірами, і фіксує його як домовленість, а не як факт.

    Lighthouse CI і бюджети продуктивності

    у CI має власний артефакт — (performance budget): набір обмежень, накладених на метрики, що впливають на продуктивність сайту. Це може бути загальний розмір сторінки, час її завантаження в мобільній мережі або навіть кількість надісланих HTTP-запитів. Роль бюджету канон формулює як точку відліку для рішень щодо дизайну, технологій і додавання функцій, і підпирає мотивом, який варто цитувати дослівно: хороша продуктивність рідко буває побічним ефектом.

    Складається бюджет із трьох класів метрик: кількісних (максимальний розмір зображень, кількість вебшрифтів, розмір скриптів разом із фреймворками, загальна кількість зовнішніх ресурсів), часових віх (події при завантаженні сторінки, і найкорисніші тут — користувацькі метрики, доступні через API браузера й у звітах Lighthouse) і правил-балів (Lighthouse і WebPageTest рахують бали за загальними правилами кращих практик). Канон радить комбінацію, а не один клас, і застерігає: кількісні межі мало кажуть про досвід, бо дві сторінки з однаковою кількістю запитів або однаковою вагою можуть рендеритися по-різному залежно від порядку, у якому запитуються ресурси.

    Формулюють бюджет разом із контекстом виміру — сторінкою, пристроєм і мережею: «сторінка товару має віддавати менше ніж 170 КБ JavaScript на мобільному», «блог має мати бал понад 80 в аудиті продуктивності Lighthouse». Числа тут не абсолютні: джерело прямо каже, що вони пораховані на основі реальних базових пристроїв і швидкості мережі 3G, а сама сторінка датована 2018 роком — тож цитувати їх можна лише разом із датою й умовами. Чинний набір клієнтських метрик розбирає глава про фронтенд-продуктивність і Core Web Vitals.

    Гейтом бюджет робить перелік із трьох дій при перевищенні: оптимізувати наявну функцію чи ресурс, прибрати наявну функцію чи ресурс або не додавати нову. Третя дія і є суттю: бюджет змушує вибирати, а не просто повідомляє. Технічно він живе у збірці — канон називає можливості продуктивності Webpack, bundlesize і Lighthouse CI, — а сам Lighthouse CI описує свою роль сумісно: задавати й тримати бюджети продуктивності на скрипти й зображення. На боці навантажувального тесту ту саму роль виконують пороги; різниця лише в предметі виміру.

    Одне застереження, без якого бал Lighthouse у гейті приносить більше шкоди, ніж користі. Підсумковий бал — це позиція відносно решти вебу: сире значення метрики перетворюється на бал за положенням у логнормальному розподілі, побудованому на реальних даних HTTP Archive. Ваги метрик змінюються між версіями інструмента, тож бали, зняті різними версіями, незіставні — версію в CI закріплюють так само, як версію . І головне: сам інструмент радить думати про продуктивність як про розподіл балів, а не про одне число, — тобто один прогін Lighthouse гейтом не є. Плюс межа лабораторного виміру: це один пристрій, одна мережа, одне географічне розташування, і реального розкиду він навмисно не відтворює. Цінність лабораторії при цьому в іншому — вона дає перевірку фічі до релізу й ловить регресію заздалегідь, там, де ще сліпі. А от гонитву за ідеальним балом суто заради SEO Google Search називає, найімовірніше, не найкращим витрачанням часу.

    Тренд і зберігання історії результатів

    Тренд не існує сам собою — він існує рівно настільки, наскільки збережені результати. Тут корисно розрізняти дві форми виводу, які дає інструмент навантаження: агрегована статистика прогону або окремі точки з мітками часу. Перша відповідає на питання «пройшли чи ні», друга — на питання «коли саме почалася деградація», і саме вона годиться для порівняння прогонів між собою: агрегати різних прогонів не складаються. Потік точок пишуть у файл або стрімлять у сервіс.

    На фронтенді ту саму задачу закриває Lighthouse CI, і його самоозначення варто прочитати як перелік обов'язків: безперервно ганяти, зберігати, діставати й перевіряти результати Lighthouse. У переліку можливостей це розкладено детальніше — відстеження метрик і балів у часі та порівняння двох версій сайту, щоб знайти покращення й регресії окремих ресурсів. Останнє й відрізняє тренд від дашборда: питання не «бал упав», а «що саме потовстішало». Під зберігання історії в проєкті передбачено окремий сервер — тобто сховище є частиною конструкції, а не бонусом.

    Дві дрібниці, які роблять історію придатною до вжитку. По-перше, закріплена версія інструмента — і генератора навантаження, і CLI Lighthouse (у канонічному прикладі це @0.15.x): без цього ряд точок змішує зміни системи зі змінами вимірювача. По-друге, вимір не закінчується релізом: канон бюджету прямо каже, що переконатися, що сайт достатньо швидкий, означає продовжувати міряти після початкового запуску, а моніторинг метрик у часі й дані від реальних користувачів показують, як зміни в продуктивності впливають на бізнес-метрики. Другу половину цієї пари — збір із проду — розбирає глава про моніторинг, APM і спостережуваність.

    Типові помилки

    • «Той самий коміт дав інші числа — тест флакітний» → виглядає як дефект тесту, а насправді одиничний перф-вимір шумний за побудовою, і задокументована відповідь на це — прогнати аудит багато разів, щоб зменшити дисперсію, а не послабити критерій.
    • «Порівняли з прогоном тижневої давнини — просіли на 15%» → виглядає як регресія, а насправді час є одним із найбільших джерел зміни спостережуваних метрик: реліз у понеділок порівнює робочий день із вихідними й вносить великий обсяг шуму.
    • «Поставили гейт на утилізацію процесора — це найчутливіша метрика» → виглядає як рання діагностика, а насправді зростання витрат ресурсу не обов'язково впливає на сервіс і може дати шумний, нестабільний процес; шумний процес оператори можуть вимкнути або почати ігнорувати, і сама ідея гейта знецінюється.
    • «Гейт червоний — винен наш реліз» → виглядає як спрацювання за призначенням, а насправді сильно перевантажена сусідня машина є проблемою, але не спричинена зміною, яку ми перевіряємо, тож провалом позначатися не має.
    • «Порівнюємо сорок метрик, щоб нічого не проґавити» → виглядає як ретельність, а насправді забагато метрик дають спадну віддачу, і з певного моменту вигоду перекриває вартість підтримки або втрата довіри до релізного процесу; канон радить не більш ніж дюжину.
    • «Гейт не спрацював жодного разу за квартал — отже, все добре» → виглядає як доказ стабільності, а насправді одне порогове правило має сліпу зону: швидкість витрачання 35 не спрацьовує ніколи, хоча з'їдає весь місячний бюджет помилок за 20,5 години.
    • «Ганяємо на ubuntu-latest, залізо однакове» → виглядає як контрольована умова, а насправді та сама мітка дає 4 процесори в публічному репозиторії й 2 у приватному (станом на 2026-08-01), а образи -latest є лише останніми стабільними й можуть не бути найсвіжішою версією ОС; що виконувало джобу, видно тільки в логах прогону.
    • «Сторінка важить стільки ж, отже швидкість та сама» → виглядає як арифметика, а насправді дві сторінки з однаковою вагою або однаковою кількістю запитів рендеряться по-різному залежно від порядку, у якому запитуються ресурси.

    Підсумок

    • У пайплайні перф-тест відповідає на питання «чи погіршила це зміна», а не «скільки система тримає». Через короткий доступний час у CI живе підмножина тестів; повний профіль ганяється за розкладом або руками, і канон це прямо передбачає.
    • Гейтом прогін робить поріг, а не звіт. Єдиний інтерфейс до пайплайна — код виходу; джоба без порогів не блокує нічого, а джоба, пропущена умовою, лишає гейт зеленим.
    • Порівняння «до й після» ненадійне за побудовою, бо час — одне з найбільших джерел зміни метрик. Сильніші конструкції — серія прогонів на одному коміті й паралельний контроль; розкид лікують повтореннями, а не ширшим порогом.
    • Метрика гейта мусить бути віднесеною до зміни. Коди відповіді й затримка — так, утилізація процесора — ні: шумний критерій вимикають, і разом із ним помирає вся ідея.
    • Тренд існує рівно настільки, наскільки збережені результати. Потрібні окремі точки з мітками часу, сховище історії й закріплені версії інструментів — інакше ряд змішує зміни системи зі змінами вимірювача.

    Можливі питання

    • «Який перф-тест ви поставите на кожен PR?» — перевіряють відчуття вартості: очікують смоук на хвилини з грубими критеріями, а не «маленький load». Сильна відповідь одразу називає, що саме він ловить — зламаний сценарій і явні відмови — і що тонкі метрики на цьому рівні не читають.
    • «Ви порівнюєте прогін на PR із прогоном минулого тижня. Що з цим не так?» — питання про час як змінну. Дивляться, чи назве кандидат шум, який вносить сама відстань у часі, і чи запропонує повтори на одному коміті або паралельний контроль.
    • «На що ви поставите поріг у CI — на абсолютне число чи на дельту від базового виміру?» — очікують не вибір, а розбір: абсолютний поріг перевіряє вимогу й мовчить про повільну систему, дельта ловить регресію й мовчить про давню повільність. Згадка про гейт «лише на новий код» додає ваги.
    • «Ваш перф-гейт тиждень блимає червоним. Що робите?» — перевіряють, чи розуміє кандидат, що шумний гейт помирає: його вимикають або ігнорують. Сильна відповідь іде до причини — метрика не віднесена до зміни, замало повторів, спільний ранер — а не до послаблення порогу.
    • «Скільки метрик ви візьмете в критерій?» — дивляться на знання про спадну віддачу й вартість підтримки; канонічний орієнтир — не більш ніж дюжина, з кодами відповіді й затримкою на першому місці.
    • «Чим бюджет продуктивності відрізняється від порога?» — предметом виміру: бюджет обмежує вагу й час завантаження сторінки, поріг — метрики прогону під навантаженням. Плюс три дії при перевищенні, третя з яких — не додавати нову функцію.
    • «Чому не можна просто поставити гейт на бал Lighthouse?» — питання рівня сеньйора: бал є позицією відносно розподілу реальних даних, ваги метрик змінюються між версіями інструмента, а сам інструмент радить думати про розподіл балів, а не про одне число.
    • «Де ви зберігаєте результати перф-прогонів і навіщо?» — очікують розрізнення агрегованого підсумку й окремих точок із мітками часу, згадку про сховище історії й закріплені версії інструментів.

    Джерела

    Що перф-тест робить у пайплайні — і чого не робить

    • ISTQB® CT-PT — Foundation Level Specialist Syllabus, Performance Testing v1.0 (2018) — головна мета перф-тестів у CI, тести в пайплайні як підмножина ширших через короткий доступний час, вимога починати аналіз ризиків рано й повторювати регулярно.
    • Grafana k6 — Automated performance testing — не всі перф-тести придатні для CI/CD, запуск тільки з CI обмежує цілі, cron і ручний запуск як названі альтернативи, перехід із реактивного режиму в проактивний.

    Перф-смоук на PR: найдешевший рівень

    • ISTQB® CT-PT — Foundation Level Specialist Syllabus, Performance Testing v1.0 (2018) — базовий вимір як набір метрик для порівняння, створення базового виміру на знеособлених даних, неможливість оцінити результати прогону без базових вимірів.
    • Grafana k6 — Load test types — порада починати зі смоуку й перевіряти працездатність скриптів; параметри смоуку: низьке навантаження, секунди-хвилини, привід — зміна коду, перевірка логіки, базових метрик і відхилень.
    • Grafana k6 — Automated performance testing — порівняння з наявним базовим виміром як перша ціль регулярних прогонів.

    Поріг як гейт релізу, а не як вердикт прогону

    • Grafana k6 — Thresholds — код виходу 0 при виконаних порогах і ненульовий при провалі як єдиний інтерфейс прогону до CI; поріг як кодифікація SLO.
    • Grafana k6 — Checks — невдалі чеки не валять прогін, ведеться лише облік їхньої частки, і чек блокує щось лише в парі з порогом.
    • ISTQB® CT-PT — Foundation Level Specialist Syllabus, Performance Testing v1.0 (2018) — критерії приймання для всіх релевантних вимірів і їх прив'язка до цілей тесту, SLA та базових значень.
    • Google Testing Blog — Code Coverage Best Practices — розвилки форми гейта: усе проти лише нового коду, жорстко задане число проти дельти від попередньої версії; ризик перетворення гейта на чекбокс і теза про тиск «влучити в метрику».
    • GitHub Docs — About protected branches — обов'язкова перевірка проходить у станах successful, skipped або neutral, тож пропущена джоба лишає гейт зеленим.
    • GitHub Docs — Continuous integration (GitHub Actions) — зелений прогін означає лише готовність до рецензії або злиття, а не апрув.
    • Git Reference — githookspre-commit обходиться опцією --no-verify, тож хук лишається швидким фідбеком, а не блокуванням.
    • ISTQB Certified Tester Foundation Level Syllabus v4.0 — §2.1.4: CI просуває shift-left, підштовхуючи віддавати код разом із компонентними тестами й статичним аналізом.

    Порівняння з базовим виміром: що з чим і за якою метрикою

    • Google SRE Workbook — Chapter 16: Canarying Releases — час як найбільше джерело зміни метрик і ненадійність порівняння «до й після», приклад понеділка проти вихідних, спільні домени відмови, вибір метрик (коди й затримка проти утилізації процесора), шумний процес вимикають, ліміт у дюжину метрик, виключення 4xx, віднесеність метрики до зміни.
    • Google SRE Workbook — Chapter 5: Alerting on SLOs — чотири властивості критерію (точність, повнота, час виявлення, час скидання) і сліпа зона однопорогового правила зі швидкістю витрачання 35.
    • GoogleChrome/lighthouse-ci — README — прогін багато разів заради зменшення дисперсії.
    • ISTQB® CT-PT — Foundation Level Specialist Syllabus, Performance Testing v1.0 (2018) — базовий вимір як набір метрик для порівняння поточних і раніше досягнутих вимірів.
    • Grafana k6 — Automated performance testing — базовий вимір, тренд і виявлення регресій релізів як три окремі цілі регулярних прогонів.
    • Grafana k6 — Results output — для порівняння прогонів придатні окремі точки з мітками часу; розбір форм — у підрозділі про історію результатів.
    • grafana/setup-k6-action — README — закріплення версії інструмента, без якого зміна цифр може бути наслідком оновлення.
    • GitHub Docs — GitHub-hosted runners reference — машина, на якій виконується порівняння; наслідки спільного заліза — в окремому підрозділі нижче.

    Рівні запуску: PR-смоук, нічний load, релізний повний

    Шум спільного ранера

    • GitHub Docs — GitHub-hosted runners reference — специфікації Linux-ранера для публічного й приватного репозиторію станом на 2026-08-01, незакріпленість образів -latest і рядок про ранер у логах прогону.
    • grafana/setup-k6-action — README — усталене встановлення останньої версії інструмента, якщо версію не задано явно.
    • Google SRE Workbook — Chapter 16: Canarying Releases — викиди у великій популяції машин, перевантажений сусід як проблема, що не є провалом перевірюваної зміни, і вибір метрики, віднесеної до самої роботи.
    • Google SRE Workbook — Chapter 5: Alerting on SLOs — властивості критерію, за якими оцінюють, чи гейт узагалі придатний до вжитку.
    • GoogleChrome/lighthouse-ci — README — повторення прогонів як задокументована відповідь на дисперсію виміру.
    • Grafana k6 — Results output — форма результату, у якій зберігається мітка часу кожної точки, потрібна для розбору розкиду.
    • Grafana k6 — Automated performance testing — регулярність прогонів як спосіб побачити варіацію, а не одиничне число.

    Lighthouse CI і бюджети продуктивності

    • web.dev — Performance budgets 101 — означення бюджету продуктивності й трьох класів метрик, вимога комбінувати класи, застереження про порядок завантаження ресурсів, приклади формулювань зі сторінкою, пристроєм і мережею, умовність чисел (базові пристрої й 3G), три дії при перевищенні та інструменти вбудовування бюджету в збірку.
    • GoogleChrome/lighthouse-ci — README — роль інструмента: задавати й тримати бюджети продуктивності на скрипти й зображення, звіт поруч із кожним PR, багаторазовий прогін заради зменшення дисперсії.
    • Grafana k6 — Thresholds — пороги як відповідник бюджету на боці навантажувального прогону: кодифікація SLO й провал тесту при невиконанні.
    • Chrome for Developers — Lighthouse Performance scoring — бал як положення в логнормальному розподілі даних HTTP Archive, зміна ваг між версіями інструмента й порада думати про розподіл балів, а не про одне число.
    • web.dev — Why lab and field data can be different (and what to do about it) — лабораторний вимір як один пристрій, одна мережа й одне розташування, що навмисно не відтворює реальний розкид.
    • web.dev — Web Vitals — місце лабораторного інструмента в процесі: перевірка до релізу й раннє виявлення регресії.
    • Google Search Central — Understanding page experience in Google Search results — застереження проти гонитви за ідеальним балом як самоціллю.

    Тренд і зберігання історії результатів

    • Grafana k6 — Results output — дві форми результату: агрегована статистика проти окремих точок із мітками часу, і запис потоку у файл або стрімінг у сервіс.
    • GoogleChrome/lighthouse-ci — README — безперервний прогін, збереження, отримання й перевірка результатів, відстеження метрик і балів у часі, порівняння двох версій до окремого ресурсу, окремий сервер під історію, закріплена версія CLI у прикладі.
    • grafana/setup-k6-action — README — усталене встановлення останньої версії, через яке версію інструмента доводиться закріплювати явно.
    • Google SRE Workbook — Chapter 16: Canarying Releases — час як джерело зміни метрик, через яке ряд точок цінніший за пару «до й після».
    • Google SRE Workbook — Chapter 5: Alerting on SLOs й час скидання як властивості, що визначають придатність критерію поверх ряду.
    • GitHub Docs — GitHub-hosted runners reference — рядок про ранер у логах прогону як частина метаданих, без якої точка ряду не інтерпретується.
    • Grafana k6 — Automated performance testing — спостереження за пласким або змінним трендом як окрема ціль регулярних прогонів.
    • web.dev — Performance budgets 101 — вимір не закінчується релізом: продовжувати міряти після початкового запуску, моніторинг метрик у часі й дані реальних користувачів як показник впливу на бізнес-метрики.

    Пояснення

    «Поясни» працює з власним API-ключем Anthropic: запит іде з вашого браузера прямо до Anthropic.

    Свій API-ключ (BYOK)

    Вставте власний ключ Anthropic — пояснення працюватиме на реальній моделі. Ключ зберігається лише у вашому браузері (localStorage), нікуди не надсилається, крім api.anthropic.com, і не логується.