Доброго времени суток, друзья!
В данной статье мы познакомимся с Intersection Observer API, новым мощным инструментом для «ленивой» загрузки изображений и других элементов на странице, поддерживаемым всеми современными браузерами. Мы можем использовать этот инструмент для управления видимостью элементов, определяя предварительную или отложенную загрузку контента нашего DOM.
По мере развития «веба» браузеры поддерживают все больше и больше новых возможностей и API, но кое-что по-прежнему причиняет боль разработчикам — рендеринг DOM. Когда мы начинаем разработку нового приложения, создаем компоненты, продумываем структуру HTML, стилизуем элементы средствами CSS, мы также задумываемся о процессе рендеринга, о том, как наша страница будет выглядеть в целом, и еще о некоторых важных вещах, требующих осторожного обращения и влияющих на рендеринг приложения.
Это, в свою очередь, влияет на то, как мы будем создавать наши элементы, как будет организован наш CSS, какие библиотеки и фреймворки будут использоваться в проекте и т.д. Вот почему рендеринг так важен для разработчиков.
Одной из причин популярности библиотеки React в сообществе разработчиков является тот факт, что в ней используется виртуальный DOM. По сути, это виртуальное представление реального DOM, которым можно управлять по своему усмотрению. После всех обновлений виртуальный DOM решает, какие изменения необходимо внести в оригинальный DOM, и производит эти изменения «бесшовным» способом; нет нужды обновлять страницу целиком при изменении одного элемента. В этом заключается одно из наиболее существенных преимуществ React перед другими библиотеками и фреймворками. Рендеринг DOM — дорогостоящая (с точки зрения производительности) задача, с которой React прекрасно справляется без каких бы то ни было проблем.
Некоторые библиотеки и API позволяют улучшить рендеринг элементов наших приложений. Мы собираемся познакомиться с одним из них — Intersection Observer API. Но для начала давайте разберемся с тем, что такое «ленивая» загрузка изображений.
Как работает «ленивая» загрузка изображений?
«Ленивая» загрузка — одна из техник для рендеринга содержимого страницы. Концепция «ленивой» загрузки состоит в том, что вместо полной загрузки страницы, мы загружаем только необходимые части и откладываем (задерживаем) загрузку остальных частей до тех пор, пока они не понадобятся пользователю.
Примером «ленивой» загрузки, о котором вы наверняка слышали или с которым вам приходилось сталкиваться, является бесконечная прокрутка страницы. Это работает примерно так: пользователь заходит на страницу, загружается начальный контент, и только после того, как пользователь прокрутил страницу вниз до самого конца, загружается следующая порция содержимого. В данном случае отсутствует потребность загружать весь контент сразу, что существенно облегчает приложение.
Если «ленивая» загрузка служит для загрузки только «пользовательского» контента, как называется противоположная техника? Некоторые слышали о «ленивой» загрузке раньше, но не слышали об обратном. Противоположностью «ленивой» загрузки является «энергичная» загрузка (другие варианты — нетерпеливая, стремительная) — когда сразу рендерится весь контент.
Знаете ли вы, что существуют HTML-атрибуты для «ленивой» загрузки изображений? Для того, чтобы их использовать, достаточно добавить loading=«lazy» в элемент «img» или «iframe».
При использовании данной техники мы получаем массу преимуществ: загрузка только необходимых ресурсов снижает потребление памяти и, в конечном счете, время загрузки страницы. Это также препятствует рендерингу «невостребованного» кода, что оптимизирует приложение для работы в условиях низкой пропускной способности сети. Однако существует и некоторые недостатки: это может влиять на ранжирование страницы поисковиками. Кроме того, требуется некоторое время на выбор правильной библиотеки или API для работы.
Intersection Observer API
JavaScript развивается настолько быстро, что мы получаем новый API почти каждый год. Основной задачей новых API является помощь в создании потрясающих приложений и страниц.
Intersection Observer — это API, позволяющий наблюдать за видимостью и позицией элементов DOM. Штука в том, что он работает асинхронно, позволяя плавно (незаметно) менять видимость элементов, определяя предварительную или отложенную загрузку контента нашего DOM.
Несколько лет назад у нас не было API или другого инструмента для определение позиции и слежения за элементом. Нам приходилось писать сумасшедшие и огромные функции, создавать дорогие (в плане производительности) методы, которые создавали больше проблем. С помощью Intersection Observer API мы можем делать такие прикольные вещи, как:
- Бесконечная прокрутка страницы — создавать бесконечную прокрутку таблиц, списков, грид-контейнеров и т.п. никогда не было так просто.
- Изображения — зачем загружать все картинки сразу, когда можно воспользоваться «ленивой» загрузкой и отображать только тот контент, который нужен пользователю в данный момент?
- Мониторинг элементов — вы можете наблюдать за элементами на странице. Например, вы можете получать сообщения о закрытии рекламных объявлений.
Вот с чего все начинается:
let myFirstObserver = new IntersectionObserver(callback, options)
Мы инициализируем конструктор IntersectionObserver и передаем ему два параметра. Первым параметром является функция обратного вызова, которая вызывается в ответ на пересечение нашего элемента с областью просмотра (т.е. когда элемент выходит за границы области просмотра) или с другим элементом. Параметр «options» — это объект, контролирующий условия запуска функции обратного вызова. У данного объекта имеются следующие поля:
- root — родительский элемент, служащий областью просмотра для целевого элемента (для элемента, за которым мы наблюдаем)
- rootMargin — внешний отступ вокруг элемента «root» (значения этого поля аналогичны значениям «margin» в CSS). Эти значения могут меняться для каждой стороны root перед фиксацией пересечения
- threshold — число или массив чисел, определяющий процент пересечения целевого элемента с элементом «root», при котором запускается функция обратного вызова
Давайте посмотрим на использование Intersection Observer API:
let options = {
root: document.querySelector('.scroll-list'),
rootMargin: '5px',
threshold: 0.5
}
let myFirstObserver = new IntersectionObserver(elements => { elements.forEach(element => console.log('element', element)) }, options)
Для того, чтобы начать «следить» за элементом, необходимо определить цель и вызвать observer с помощью метода «observe», передав ему цель в качестве параметра:
let myDivTarget = document.querySelector('.header')
observer.observe(myDivTarget)
Следует помнить, что все элементы, за которыми наблюдает observer, являются прямоугольниками. Элементы неправильной формы вписываются в наименьший прямоугольник.
Что насчет поддержки браузерами? Intersection Observer API поддерживается всеми современными браузерами, такими как Chrome, Edge, Firefox и Opera.
Если вы собираетесь работать с большим количеством данных, например, с таблицей, содержащей большое количество информации, Intersection Observer API будет вам крайне полезен.
Одним из преимуществ данного API является то, что для решения подобных задач больше не нужно использовать какую-либо библиотеку.
Заключение
Мы изучили Intersection Observer API и его использование для «ленивой» загрузки, наблюдения за позицией элементов DOM и т.д. Браузеры поддерживают все больше и больше API, снижающих время рендеринга страниц, в первую очередь, для пользователей с медленным соединением, уменьшая размер проекта и отображая лишь востребованный контент.
От переводчика: статья показалась мне недостаточно информативной, поэтому вот ссылки на дополнительную литературу:
- Спецификация
- Статья про Intersection Observer API на MDN (русский)
- Статья с примерами на CSS Tricks (английский)
- Статья с примерами на Envato (английский)
- Пример бесконечной прокрутки от Google
- Еще парочка примеров на GitHub
Благодарю за внимание.
SelenIT3
Спасибо за перевод!
К вопросу о полезных примерах использования IntersectionObserver-а, можно вспомнить еще занятный способ эмуляции "media query на уровне компонентов" на его основе.