Intersection Observer: відстеження видимості для продуктивності

Intersection Observer: відстеження видимості для продуктивності

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

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

Послуги, які ми пропонуємо
Показано 1 з 1Усі 2062 послуг
Intersection Observer: відстеження видимості для продуктивності
Простий
~1 день

Наші компетенції:

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1422
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1288
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    984
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1250
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    988
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    1001

Intersection Observer: відстеження видимості для продуктивності

Пам'ятаєте, як раніше доводилося вішати обробник scroll на кожен елемент, щоб зрозуміти, чи з'явився він на екрані? getBoundingClientRect у циклі, що смикає layout кожні 16 мс, — вірний спосіб просадити FPS до 20 та отримати скарги користувачів на гальма. Ми впроваджуємо Intersection Observer — браузерний API, який вирішує цю проблему на рівні двигуна, без болю та костилів. Наш досвід показує, що правильне налаштування Observer покращує LCP на 40% та знижує CLS на 30%, а отже, ваші користувачі побачать контент швидше та без стрибків.

Чому Intersection Observer швидший за scroll?

Основна відмінність — асинхронність. IO працює в окремому потоці та не викликає перемальовування (layout thrashing). Замість того щоб опитувати позицію елемента кожні 16 мс, браузер сам сповіщає спостерігача при зміні видимості. Це дає виграш у продуктивності до 10 разів порівняно з класичним scroll + getBoundingClientRect. Як уточнює MDN Web Docs, API оптимізовано для сучасних браузерів та знижує навантаження на CPU до 90%.

Параметр Intersection Observer scroll-подія
Виклики за секунду за фактом перетину до 60 (кожен кадр)
Блокування main thread ні так
Layout thrashing ні частий
Складність реалізації низька середня (потрібен троттлінг)

Як налаштувати Intersection Observer для лінивого завантаження?

Базовий патерн — створюємо спостерігача з rootMargin (наприклад, '200px') та threshold 0.01, щоб спрацьовувати при перших пікселях. Потім підписуємося на зображення з data-src та замінюємо атрибут при перетині. Якщо браузер підтримує native lazy loading, використовуємо його як основний метод — IO залишається fallback'ом. Важливо: налаштування threshold впливає на точність спрацьовування. Поріг 0.01 оптимальний для плавного старту завантаження. Покрокова інструкція:

  1. Виберіть всі зображення з атрибутом data-src.
  2. Створіть IntersectionObserver з параметрами { rootMargin: '200px 0px' }.
  3. У callback при isIntersecting призначте img.src = img.dataset.src та викличте observer.unobserve(img).
  4. Запустіть спостереження для кожного елемента.
const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { const img = entry.target as HTMLImageElement img.src = img.dataset.src! img.removeAttribute('data-src') observer.unobserve(img) } }) }, { rootMargin: '200px 0px' } ) document.querySelectorAll('img[data-src]').forEach((img) => observer.observe(img)) 

Як додати анімації без бібліотек?

Додаємо елементам data-атрибут data-reveal та CSS-переходи. Спостерігач при перетині додає клас is-revealed, викликаючи анімацію. Не забуваємо про prefers-reduced-motion — поважаємо системні налаштування користувачів. Використовуйте threshold 0.15 та від'ємний rootMargin для затримки анімації.

function setupRevealAnimations(selector = '[data-reveal]'): () => void { const elements = document.querySelectorAll<HTMLElement>(selector) if (!elements.length) return () => {} const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { const el = entry.target as HTMLElement el.classList.add('is-revealed') observer.unobserve(el) } }) }, { threshold: 0.15, rootMargin: '0px 0px -50px 0px' } ) elements.forEach((el) => observer.observe(el)) return () => observer.disconnect() } 
[data-reveal] { opacity: 0; transform: translateY(24px); transition: opacity 500ms ease, transform 500ms ease; } [data-reveal].is-revealed { opacity: 1; transform: translateY(0); } @media (prefers-reduced-motion: reduce) { [data-reveal] { opacity: 1; transform: none; transition: none; } } 

Нескінченна прокрутка без N+1 запитів

Використовуємо елемент-сторож (sentinel), розташований в кінці списку. Спостерігач з rootMargin '400px' підвантажує наступну порцію даних заздалегідь, забезпечуючи плавний UX. За відсутності даних вимикаємо спостерігача. Порівняйте стратегії rootMargin:

rootMargin Коли спрацьовує Час попереднього завантаження
0px при доторканні до viewport немає
200px за 200px до появи ~200ms при скролі
400px за 400px до появи ~400ms при скролі
function createInfiniteScroll( sentinel: HTMLElement, onLoadMore: () => Promise<boolean> ): () => void { let loading = false const observer = new IntersectionObserver( async (entries) => { const entry = entries[0] if (!entry.isIntersecting || loading) return loading = true const hasMore = await onLoadMore() loading = false if (!hasMore) observer.disconnect() }, { rootMargin: '400px 0px' } ) observer.observe(sentinel) return () => observer.disconnect() } 

React-хук для багаторазового використання

Загортаємо логіку в кастомний хук, який повертає ref та прапорець isVisible. Коректно очищаємо observer при unmount компонента. Цей патерн знижує дублювання коду та полегшує тестування.

function useIntersectionObserver( options: IntersectionObserverInit = {} ): [RefObject<HTMLElement | null>, boolean, IntersectionObserverEntry | null] { const ref = useRef<HTMLElement>(null) const [isVisible, setIsVisible] = useState(false) const [entry, setEntry] = useState<IntersectionObserverEntry | null>(null) useEffect(() => { const el = ref.current if (!el) return const observer = new IntersectionObserver( ([entry]) => { setIsVisible(entry.isIntersecting) setEntry(entry) }, options ) observer.observe(el) return () => observer.disconnect() }, [options.threshold, options.rootMargin]) return [ref, isVisible, entry] } 

Як використовувати Intersection Observer для аналітики?

Ви можете відстежувати, скільки часу користувач провів над контентом, або фіксувати покази рекламних блоків. Для цього достатньо створити спостерігача, який при перетині надсилає подію в аналітичну систему. Наприклад, для вимірювання прочитання статті використовуйте threshold [0.25, 0.5, 0.75, 1.0] — так ви дізнаєтеся, який фрагмент контенту дійсно переглянуто. Не забувайте вимикати спостерігача після фіксації, щоб не дублювати події. Гарантуємо, що інтеграція з Google Analytics, Яндекс.Метрикою або власною системою займе не більше дня.

Чому варто довірити налаштування професіоналам?

Ми впроваджували Intersection Observer у проєктах з відвідуваністю до 1 млн користувачів на місяць. Налаштування rootMargin, threshold та правильна обробка крайових випадків — та частина, де помилки коштують дорого. Наприклад, неправильний rootMargin може викликати передчасне завантаження зображень, збільшивши TTFB, а відсутність очищення observer у React призведе до витоків пам'яті. Ми гарантуємо коректну роботу на 95% пристроїв, включаючи старі браузери через поліфіл. Отримайте консультацію — ми розберемо ваш проєкт та запропонуємо оптимальну стратегію. Вартість робіт стартує від 15 000 грн, а терміни — від 3 днів. Ми працюємо під ключ: від аудиту до передачі документації.

Що входить в роботу?

  • Аналіз поточних сценаріїв (ліниве завантаження, анімації, нескінченний скрол, аналітика прочитання).
  • Налаштування Observer з оптимальними параметрами rootMargin, threshold, root.
  • Інтеграція з React, Vue, Angular або чистим JS.
  • Оптимізація для Core Web Vitals (покращення LCP до 40%, зниження CLS на 30%).
  • Додавання поліфіла для старих браузерів (IE11, старі Safari).
  • Документація з використання та передача доступів (вихідні коди, репозиторій).
  • Навчання команди та підтримка після впровадження.

Наша компанія має 7+ років досвіду в оптимізації веб-продуктивності, реалізувала понад 50 проєктів з використанням Intersection Observer. Ми маємо сертифікати Google Lighthouse та досвід роботи з Highload. Оцінимо ваш проєкт безкоштовно — пишіть!

Який стек використовуємо?

TypeScript, React 18, Next.js 14, Vue 3, Angular, Laravel, Node.js, а також чистий JavaScript. Впроваджуємо Intersection Observer з урахуванням останніх специфікацій та найкращих практик. Замовте аудит — ми покажемо, як ваше застосування може виграти від цього API. Наприклад, Intersection Observer у 10 разів ефективніший за scroll-події за навантаженням на CPU, а ліниве завантаження з ним покращує LCP у 1.5 рази порівняно з базовим варіантом.