Дізнайтеся, як Performance Observer API надає потужний, ненав'язливий спосіб моніторингу продуктивності вебсайтів у реальному часі, відстеження Core Web Vitals та оптимізації користувацького досвіду.
Розблокування веб-продуктивності: глибоке занурення в Performance Observer API
У сучасному швидкоплинному цифровому світі веб-продуктивність – це не розкіш, а необхідність. Повільний або нереагуючий веб-сайт може призвести до розчарування користувачів, збільшення показників відмов і прямого негативного впливу на бізнес-цілі, будь то продажі, дохід від реклами чи залучення користувачів. Протягом багатьох років розробники покладалися на інструменти, які вимірюють продуктивність в одній точці часу, зазвичай під час початкового завантаження сторінки. Хоча це корисно, такий підхід пропускає критичну частину історії: повний досвід користувача під час взаємодії зі сторінкою. Саме тут на допомогу приходить моніторинг продуктивності в реальному часі, і його найпотужнішим інструментом є Performance Observer API.
Традиційні методи часто передбачають опитування даних про продуктивність за допомогою таких функцій, як performance.getEntries(). Це може бути неефективним, схильним до пропуску важливих подій, які відбуваються між опитуваннями, і навіть може збільшити накладні витрати на продуктивність, які він намагається виміряти. Performance Observer API революціонізує цей процес, надаючи асинхронний механізм з низькими накладними витратами для підписки на події продуктивності в міру їх виникнення. Цей посібник проведе вас у глибоке занурення в цей важливий API, показуючи, як використати його потужність для моніторингу Core Web Vitals, виявлення вузьких місць і, зрештою, створення швидших і приємніших веб-додатків для глобальної аудиторії.
Що таке Performance Observer API?
По суті, Performance Observer API — це інтерфейс, який надає спосіб спостерігати та збирати події вимірювання продуктивності, відомі як записи про продуктивність. Уявіть собі це як спеціальний прослуховувач для дій, пов’язаних із продуктивністю, у браузері. Замість того, щоб ви активно запитували браузер: «Чи вже щось сталося?», браузер активно повідомляє вам: «Щойно сталася нова подія продуктивності! Ось деталі».
Це досягається за допомогою шаблону спостерігача. Ви створюєте екземпляр спостерігача, повідомляєте йому, які типи подій продуктивності вас цікавлять (наприклад, великі відмальовки, введення користувача, зсуви макета), і надаєте функцію зворотного виклику. Щоразу, коли в часовій шкалі продуктивності браузера реєструється нова подія вказаного типу, викликається ваша функція зворотного виклику зі списком нових записів. Ця асинхронна модель на основі push-повідомлень набагато ефективніша та надійніша, ніж старіша модель на основі pull-повідомлень із повторними викликами performance.getEntries().
Старий спосіб проти нового
Щоб оцінити інноваційність Performance Observer, давайте порівняємо два підходи:
- Старий спосіб (опитування): Ви можете використовувати setTimeout або requestAnimationFrame, щоб періодично викликати performance.getEntriesByName('my-metric'), щоб перевірити, чи було записано вашу метрику. Це проблематично, оскільки ви можете перевірити занадто пізно та пропустити подію або перевіряти занадто часто та витрачати цикли ЦП. Ви також ризикуєте заповнити буфер продуктивності браузера, якщо не очищатимете записи регулярно.
- Новий спосіб (спостереження): Ви налаштовуєте PerformanceObserver один раз. Він тихо сидить у фоновому режимі, споживаючи мінімум ресурсів. Як тільки буде записано відповідний запис про продуктивність — будь то через одну мілісекунду після завантаження сторінки чи через десять хвилин сеансу користувача — ваш код миттєво отримує сповіщення. Це гарантує, що ви ніколи не пропустите подію, а ваш код моніторингу буде максимально ефективним.
Чому варто використовувати Performance Observer
Інтеграція Performance Observer API у ваш робочий процес розробки пропонує безліч переваг, які мають вирішальне значення для сучасних веб-додатків, націлених на глобальний охоплення.
- Ненав’язливий моніторинг: Зворотний виклик спостерігача зазвичай виконується в періоди простою, що гарантує, що ваш код моніторингу продуктивності не заважає користувацькому досвіду та не блокує основний потік. Він розроблений як легкий і має незначний вплив на продуктивність.
- Комплексні дані про продуктивність у реальному часі: Веб є динамічним. Проблеми з продуктивністю виникають не лише під час завантаження. Користувач може запустити складну анімацію, завантажити більше вмісту прокручуванням або взаємодіяти з важким компонентом через тривалий час після початкового завантаження сторінки. Performance Observer фіксує ці події в реальному часі, надаючи вам повну картину всього сеансу користувача.
- Перспективний і стандартизований: Це рекомендований W3C стандарт для збору даних про продуктивність. Нові показники продуктивності та API розроблено для інтеграції з ним, що робить його сталим і перспективним вибором для ваших проектів.
- Основа моніторингу реальних користувачів (RUM): Щоб дійсно зрозуміти, як ваш сайт працює для користувачів у різних країнах, на різних пристроях і в різних мережевих умовах, вам потрібні дані з реальних сеансів. Performance Observer є ідеальним інструментом для створення надійного рішення RUM, що дає змогу збирати важливі показники та надсилати їх у службу аналітики для агрегації та аналізу.
- Усуває умови гонитви: Під час опитування ви можете спробувати отримати доступ до запису про продуктивність до того, як його буде записано. Модель спостерігача повністю усуває цю умову гонитви, оскільки ваш код запускається лише після того, як запис стане доступним.
Початок роботи: основи Performance Observer
Використовувати API нескладно. Процес складається з трьох основних етапів: створення спостерігача, визначення зворотного виклику та повідомлення спостерігачу, за чим слід стежити.
1. Створення спостерігача зі зворотним викликом
Спочатку ви створюєте об’єкт PerformanceObserver, передаючи йому функцію зворотного виклику. Ця функція буде виконуватися щоразу, коли виявляються нові записи.
const observer = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { console.log('Entry Type:', entry.entryType); console.log('Entry Name:', entry.name); console.log('Start Time:', entry.startTime); console.log('Duration:', entry.duration); } });
Зворотний виклик отримує об’єкт PerformanceObserverEntryList. Ви можете викликати метод getEntries() у цьому списку, щоб отримати масив усіх нових спостережуваних записів про продуктивність.
2. Спостереження за певними типами записів
Спостерігач нічого не робить, поки ви не скажете йому, за чим стежити. Ви робите це за допомогою методу .observe(). Цей метод приймає об’єкт із властивістю entryTypes (або в деяких сучасних випадках лише type для одного типу), яка є масивом рядків, що представляють типи записів про продуктивність, які вас цікавлять.
// Почніть спостерігати за двома типами записів observer.observe({ entryTypes: ['mark', 'measure'] });
Деякі з найпоширеніших типів записів включають:
- 'resource': Деталі про мережеві запити для таких ресурсів, як сценарії, зображення та таблиці стилів.
- 'paint': Час для першої відмальовки та першої відмальовки контенту.
- 'largest-contentful-paint': Метрика Core Web Vital для швидкості завантаження, яку відчуває користувач.
- 'layout-shift': Метрика Core Web Vital для візуальної стабільності.
- 'first-input': Інформація про першу взаємодію користувача, яка використовується для First Input Delay Core Web Vital.
- 'longtask': Визначає завдання в основному потоці, які займають понад 50 мілісекунд, що може спричинити нечутливість.
- 'mark' & 'measure': Користувацькі маркери та вимірювання, які ви визначаєте у власному коді за допомогою User Timing API.
3. Зупинка спостерігача
Коли вам більше не потрібно збирати дані, рекомендується відключити спостерігача, щоб звільнити ресурси.
observer.disconnect();
Практичні випадки використання: моніторинг Core Web Vitals
Core Web Vitals — це набір конкретних факторів, які Google вважає важливими для загального користувацького досвіду веб-сторінки. Їх моніторинг є одним із найпотужніших застосувань Performance Observer API. Давайте подивимось, як виміряти кожен з них.
Моніторинг Largest Contentful Paint (LCP)
LCP вимірює продуктивність завантаження. Він позначає момент у часовій шкалі завантаження сторінки, коли основний вміст, ймовірно, завантажено. Хороший показник LCP становить 2,5 секунди або менше.
Елемент LCP може змінюватися під час завантаження сторінки. Спочатку заголовок може бути елементом LCP, але пізніше може завантажитися більше зображення та стати новим елементом LCP. Ось чому Performance Observer ідеальний — він повідомляє вам про кожного потенційного кандидата LCP під час його рендерингу.
// Спостерігайте за LCP і записуйте остаточне значення let lcpValue = 0; const lcpObserver = new PerformanceObserver((entryList) => { const entries = entryList.getEntries(); // Останній запис є найновішим кандидатом LCP const lastEntry = entries[entries.length - 1]; lcpValue = lastEntry.startTime; console.log(`LCP updated: ${lcpValue.toFixed(2)}ms`, lastEntry.element); }); lcpObserver.observe({ type: 'largest-contentful-paint', buffered: true }); // Рекомендується від’єднати спостерігача після взаємодії користувача, // оскільки взаємодія може зупинити надсилання нових кандидатів LCP. // window.addEventListener('beforeunload', () => lcpObserver.disconnect());
Зверніть увагу на використання buffered: true. Це важлива опція, яка вказує спостерігачу включати записи, які були записані *до* виклику методу observe(). Це запобігає пропуску ранньої події LCP.
Моніторинг First Input Delay (FID) та Interaction to Next Paint (INP)
Ці показники вимірюють інтерактивність. Вони визначають кількісно досвід користувача, коли він вперше намагається взаємодіяти зі сторінкою.
First Input Delay (FID) вимірює час від моменту, коли користувач вперше взаємодіє зі сторінкою (наприклад, натискає кнопку), до моменту, коли браузер фактично зможе почати обробку обробників подій у відповідь на цю взаємодію. Хороший FID становить 100 мілісекунд або менше.
Interaction to Next Paint (INP) — це новіша, більш комплексна метрика, яка замінила FID як Core Web Vital у березні 2024 року. У той час як FID вимірює лише *затримку* *першої* взаємодії, INP оцінює *загальну затримку* *усіх* взаємодій користувача протягом життєвого циклу сторінки, повідомляючи про найгіршу з них. Це дає краще уявлення про загальну чутливість. Хороший INP становить 200 мілісекунд або менше.
Ви можете відстежувати FID за допомогою типу запису «first-input»:
// Спостерігайте за FID const fidObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { const fid = entry.processingStart - entry.startTime; console.log(`FID: ${fid.toFixed(2)}ms`); // Від’єднайте після повідомлення про перший вхід fidObserver.disconnect(); } }); fidObserver.observe({ type: 'first-input', buffered: true });
Відстеження INP є дещо складнішим, оскільки воно розглядає повну тривалість події. Ви спостерігаєте за типом запису «event» і обчислюєте тривалість, відстежуючи найдовшу.
// Спрощений приклад моніторингу INP let worstInp = 0; const inpObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { // INP - це тривалість події const inp = entry.duration; // Нас цікавлять лише взаємодії, триваліші за поточну найгіршу if (inp > worstInp) { worstInp = inp; console.log(`New worst INP: ${worstInp.toFixed(2)}ms`); } } }); inpObserver.observe({ type: 'event', durationThreshold: 16, buffered: true }); // durationThreshold допомагає відфільтрувати дуже короткі, ймовірно, незначні події.
Моніторинг Cumulative Layout Shift (CLS)
CLS вимірює візуальну стабільність. Це допомагає кількісно визначити, як часто користувачі стикаються з несподіваними зсувами макета — неприємним досвідом, коли вміст переміщується на сторінці без попередження. Хороший показник CLS становить 0,1 або менше.
Показник є сукупністю всіх окремих показників зсуву макета. Performance Observer є важливим тут, оскільки він повідомляє про кожен зсув у міру його виникнення.
// Спостерігайте та обчислюйте загальний показник CLS let clsScore = 0; const clsObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { // Ми не хочемо враховувати зсуви, викликані введенням користувача if (!entry.hadRecentInput) { clsScore += entry.value; console.log(`Current CLS score: ${clsScore.toFixed(4)}`); } } }); clsObserver.observe({ type: 'layout-shift', buffered: true });
Властивість hadRecentInput важлива. Це допомагає відфільтрувати законні зсуви макета, які відбуваються у відповідь на дії користувача (наприклад, натискання кнопки, яка розгортає меню), які не повинні враховуватися в показнику CLS.
Крім Core Web Vitals: інші потужні типи записів
Хоча Core Web Vitals є чудовою відправною точкою, Performance Observer може відстежувати набагато більше. Ось кілька інших надзвичайно корисних типів записів.
Відстеження довгих завдань (`longtask`)
Long Tasks API показує завдання, які займають основний потік протягом 50 мілісекунд або довше. Це проблематично, оскільки, коли основний потік зайнятий, сторінка не може реагувати на введення користувача, що призводить до повільного або замороженого досвіду. Визначення цих завдань є ключем до покращення INP.
// Спостерігайте за довгими завданнями const longTaskObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { console.log(`Long Task Detected: ${entry.duration.toFixed(2)}ms`); // Властивість 'attribution' іноді може повідомити вам, що спричинило довге завдання console.log('Attribution:', entry.attribution); } }); longTaskObserver.observe({ type: 'longtask', buffered: true });
Аналіз часу завантаження ресурсів (`resource`)
Розуміння того, як завантажуються ваші ресурси, є основою для налаштування продуктивності. Тип запису «resource» надає вам детальні дані про час мережі для кожного ресурсу на вашій сторінці, включаючи пошук DNS, з’єднання TCP і час завантаження вмісту.
// Спостерігайте за часом завантаження ресурсів const resourceObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntries()) { // Давайте знайдемо зображення, які повільно завантажуються if (entry.initiatorType === 'img' && entry.duration > 500) { console.warn(`Slow image detected: ${entry.name}`, `Duration: ${entry.duration.toFixed(2)}ms`); } } }); // Використання 'buffered: true' майже завжди необхідно для часу завантаження ресурсів // щоб перехопити ресурси, які завантажилися до запуску цього сценарію. resourceObserver.observe({ type: 'resource', buffered: true });
Вимірювання користувацьких позначок продуктивності (`mark` і `measure`)
Іноді вам потрібно виміряти продуктивність логіки, специфічної для програми. User Timing API дозволяє створювати власні часові мітки та вимірювати тривалість між ними.
- performance.mark('start-operation'): Створює часову мітку з назвою «start-operation».
- performance.mark('end-operation'): Створює іншу часову мітку.
- performance.measure('my-operation', 'start-operation', 'end-operation'): Створює вимірювання між двома позначками.
Performance Observer може прослуховувати ці користувацькі записи «mark» і «measure», що ідеально підходить для збору даних про час для таких речей, як час рендерингу компонентів у фреймворку JavaScript або тривалість критичного виклику API та подальшої обробки даних.
// У вашому коді програми: performance.mark('start-data-processing'); // ... деяка складна обробка даних ... performance.mark('end-data-processing'); performance.measure('data-processing-duration', 'start-data-processing', 'end-data-processing'); // У вашому сценарії моніторингу: const customObserver = new PerformanceObserver((entryList) => { for (const entry of entryList.getEntriesByName('data-processing-duration')) { console.log(`Custom Measurement '${entry.name}': ${entry.duration.toFixed(2)}ms`); } }); customObserver.observe({ entryTypes: ['measure'] });
Розширені концепції та найкращі практики
Щоб ефективно використовувати Performance Observer API в професійному виробничому середовищі, враховуйте ці найкращі практики.
- Завжди враховуйте `buffered: true`: Для типів записів, які можуть виникати на початку завантаження сторінки (наприклад, «resource», «paint» або «largest-contentful-paint»), використання буферизованого прапора має важливе значення, щоб уникнути їх пропуску.
- Перевірте підтримку браузером: Хоча він широко підтримується в сучасних браузерах, завжди розумно перевірити його наявність перед використанням. Ви також можете перевірити, які типи записів підтримуються певним браузером.
- if ('PerformanceObserver' in window && PerformanceObserver.supportedEntryTypes.includes('longtask')) { // Безпечно використовувати PerformanceObserver для довгих завдань }
- Надсилайте дані в службу аналітики: Запис даних у консоль чудово підходить для розробки, але для реального моніторингу вам потрібно агрегувати ці дані. Найкращий спосіб надіслати цю телеметрію з клієнта — використовувати API navigator.sendBeacon(). Це неблокуючий механізм, розроблений для надсилання невеликих обсягів даних на сервер, і він надійно працює, навіть коли сторінка вивантажується.
- Згрупуйте спостерігачів за проблемою: Хоча ви можете використовувати одного спостерігача для кількох типів записів, часто чистіше створювати окремих спостерігачів для різних проблем (наприклад, одного для Core Web Vitals, одного для часу завантаження ресурсів, одного для користувацьких показників). Це покращує читабельність і зручність підтримки коду.
- Зрозумійте накладні витрати на продуктивність: API розроблено так, щоб мати дуже низькі накладні витрати. Однак дуже складна функція зворотного виклику, яка виконує важкі обчислення, потенційно може вплинути на продуктивність. Зберігайте зворотні виклики спостерігача легкими та ефективними. Відкладіть будь-яку важку обробку у веб-воркер або надішліть необроблені дані на свій сервер для обробки там.
Висновок: побудова культури, орієнтованої на продуктивність
Performance Observer API — це більше, ніж просто ще один інструмент; це фундаментальний зсув у нашому підході до веб-продуктивності. Він переміщує нас від реактивних, одноразових вимірювань до активного, безперервного моніторингу, який відображає справжній динамічний досвід наших користувачів у всьому світі. Надаючи надійний і ефективний спосіб фіксувати Core Web Vitals, довгі завдання, час завантаження ресурсів і користувацькі показники, він дає змогу розробникам виявляти та усувати вузькі місця продуктивності до того, як вони вплинуть на значну кількість користувачів.
Впровадження Performance Observer API є важливим кроком до створення культури, орієнтованої на продуктивність, у будь-якій команді розробників. Коли ви можете виміряти те, що має значення, ви можете покращити те, що має значення. Почніть інтегрувати цих спостерігачів у свої проекти вже сьогодні. Ваші користувачі — де б вони не були у світі — подякують вам за швидший, плавніший і приємніший досвід.