Ленивая загрузка изображений — хорошая практика улучшения производительности, при которой изображения загружаются не сразу, а отложенно, в тот момент, когда они действительно нужны — например, если юзер докрутил страницу до них. Термин «ленивая загрузка» также применяется к другим типам ресурсов, например, к CSS- и JS-файлам, но это немного другая техника, так что о ней мы сейчас говорить не будем.
Реализовать ленивую загрузку изображений на вашем сайте можно двумя способами:
- Стандартный браузерный API
- Кастомный скрипт с использованием Intersection Observer API
Если вам нужно быстрое и эффективное решение с хорошей поддержкой во всех основных браузерах (кроме Safari), вероятно, вам подойдет стандартный способ. Если же вам нужен более строгий контроль над загрузкой, стоит предпочесть кастомный JavaScript. С его помощью можно, например, создавать миниатюры для изображений перед загрузкой или вставлять анимацию при попадании изображения в фокус зрения.
Давайте взглянем поближе на каждый подход.
Стандартный браузерный подход
Браузеры предоставляют очень простой способ ленивой загрузки изображений — достаточно лишь добавить атрибут к HTML-элементу.
<img src="image.jpg" alt="..." loading="lazy">
На этой демке вы можете увидеть ленивую загрузку в действии. Чтобы пронаблюдать эффект, имеет смысл замедлить скорость загрузки в настройках браузера.
При использовании этого подхода ваши изображения по умолчанию загружаются отложенно, однако тут есть некоторые недостатки.
- Изображения все равно загружаются заблаговременно, поэтому если вы пытаетесь добиться максимальной производительности, то это не лучший выбор.
- Невозможно кастомизировать изображение перед загрузкой, если это необходимо.
Javascript-подход
Технически нам доступны две возможности для обеспечения ленивой загрузки: отслеживание события скролла (scroll) или использование Intersection Observer API. Но в плане производительности имеет смысл говорить только о второй.
Чтобы реализовать ленивую загрузку, мы добавим класс lazy к каждому изображению, которое должно быть загруженно не сразу, а также добавим картинку-плейсхолдер, которая будет отображаться до загрузки нужного файла.
<img src="https://i.stack.imgur.com/y9DpT.jpg"
data-src="https://static5.depositphotos.com/...bengal-kitten.jpg" alt="Image of a Cat"
class="lazy" />
В атрибуте src
указывается изображение-плейсхолдер, которое будет грузиться сразу и отображаться по умолчанию.
Теперь напишем скрипт, который будет отбирать все изображения с классом lazy
и добавлять к ним функциональность ленивой загрузки с использованием Intersection Observer.
document.addEventListener("DOMContentLoaded", function () {
let lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
if ("IntersectionObserver" in window) {
let lazyImageObserver = new IntersectionObserver(function (
entries,
observer
) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
let lazyImage = entry.target;
lazyImage.src = lazyImage.dataset.src;
lazyImage.classList.remove("lazy");
lazyImageObserver.unobserve(lazyImage);
}
});
});
lazyImages.forEach(function (lazyImage) {
lazyImageObserver.observe(lazyImage);
});
} else {
// Здесь может быть фоллбэк
}
});
Создаем наблюдатель IntersectionObserver и передаем ему коллбэк, который будет вызван для каждого изображения, как только оно попадет в область видимости. Этот коллбэк заменяет значение атрибута src на значение из атрибута data-src, то есть заменяет плейсхолдер на нужное изображение.
Этот метод дает большую гибкость в реализации ленивой загрузки изображений, вы можете производить любые операции с ними до отображения.
Код в действии вы можете посмотреть здесь.
0 комментариев