Lazy Load – пишем на чистом JavaScript загрузку изображений

Что такое ленивая загрузка изображений, как её можно реализовать всего в несколько строк, не подключая jQuery?

Что такое Lazy Load или ленивая загрузка изображений

Когда мы открываем страницу, мы загружаем сразу все ресурсы страницы – собираем DOM дерево из HTML, когда браузер видит ссылку, будь-то CSS, JS, IMG (Image – картинка), то сразу же загружает файл по ссылке, делая на сервер запрос. Как вы наверное уже знаете, чтобы избежать множество запросов к серверу для иконок, решили собирать их в спрайтовые изображения (спрайт):

Либо же, использовать шрифты с иконками, такие как FontAwesome. Либо же, использовать SVG (от англ. Scalable Vector Graphics — масштабируемая векторная графика). Очень классная штука, рекомендую применять всё вышеперечисленное :). Сейчас еще мэйнстрим на формат изображений webp, которые значительно уменьшают вес изображений.

Вы спросите, а причём тут вообще это? Где статья? 🙂 Чтобы добиться минимального веса страниц, нужно применять все эти рекомендации на своих проектах. И вот однажды, придумали такую классную штуку как Lazy Load. Суть её в том, что вы будете загружать только те изображения, которые попали в “вашу область видимости”. Даже, если вы открыли страницу по середине и нажали F5, будут загружены именно те изображения, которые относятся к данному участку кода.

И это, как по мне, гениально. Если представить насколько меньше станет запросов к серверу, и насколько это уменьшит размер страниц, то это “отвал башки!” 🙂

Как написать Lazy Load на JavaScript

Знакомьтесь, это IntersectionObserver . Intersection Observer API позволяет веб-приложениям асинхронно следить за изменением пересечения элемента с его родителем или областью видимости документа.
Как это выглядит на практике:

window.onload = () => {
	const observer = new IntersectionObserver((entries, observer) => {
		entries.forEach(entry => {
			if (entry.isIntersecting) {
				//console.log(entry.target.dataset.src)
				entry.target.src = entry.target.dataset.src
				observer.unobserve(entry.target)
			}
		})
	}, { threshold: 0.5 })
	document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img))
}

Что мы получим в итоге – изображения, в которых есть атрибут data-src, будут загружены по принципу “попало в область браузера – загружаю, и снимаю с этого объекта наблюдение”. observer.unobserve(entry.target) – как раз и снимает “наблюдение”. В коде есть вывод в консоль для браузера, без этой строки код будет еще меньше, он сейчас закомментирован :).

И вот если раньше, я бы подключал мною любимый jQuery, вешал на scroll обработчик, то благодаря такому коду, можно сделать всё куда проще. Кстати говоря, от jQuery сейчас тоже все отказываются, и одна из причин это оптимизация загрузки страницы, а также полный переход на чистый javascript.

Lazy Load для бекграундов на JavaScript

Сначала код:

window.onload = () => {
	const observerBg = new IntersectionObserver((entries, observer) => {
		entries.forEach(entry => {
			if (entry.isIntersecting) {
				console.log(entry.target.dataset.bg)
				entry.target.style.backgroundImage = "url('"+entry.target.dataset.bg+"')"
				observer.unobserve(entry.target)
			}
		})
	}, { threshold: 0.5 })
	document.querySelectorAll('[data-bg]').forEach(el => observerBg.observe(el))
}

Как видно, мы просто ищем атрибут [data-bg], в котором хранится путь к изображению (в данном случае браузер не будет загружать такую ссылку, т.к. посчитает эту информацию строкой) и затем добавляем атрибут style в background-image. Напоминаю, что для указания свойств, состоящих из 2 и более символов, нужно указывать через camelCase – поэтому мы пишем backgroundImage.

Таким же образом, можно добавлять\убирать какие-то классы, менять бекграунд, и т.д.

Для чего вообще применяют это API:
– «ленивая» или отложенная загрузка изображений
– бесконечная прокрутка страницы
– получение информации о видимости рекламы для целей расчета стоимости показов
– запуск процесса или анимации, находящихся в поле зрения пользователя

Какие минусы у Lazy Load?

Казалось бы, какие тут минусы, сплошные плюсы. Ан нет! Дело в поисковых роботах, которые анализируют вашу страницу на наличие в них изображений, с рабочими путями. Поэтому будьте внимательны, и если будете применять этот метод, то делайте это для менее важного контента. Например, если вы делаете это на карточке товара или новости – то скорей всего это будет не самой лучшей идеей, а вот если примените код в подгрузке товаров по клику на кнопку “показать еще” через AJAX, то ничего плохого не случится.

HTML если было не понятно:

<img alt="" data-src="/local/templates/site/img/logo.webp" class="logo-img">
<div class="port-item-new" data-bg="/upload/iblock/faf1/m01qfgi7ld3qnbfa0eglxadz7j0lmf5x.webp">..

Спасибо всем за прочтение, надеюсь было интересно :).

автор: Dmitriy

З 2011 року займаюся веб-розробкою. Зараз я – PHP Full Stack Developer.
Обговорити ваш проект, а також дізнатися більше про мене ви можете на цьому сайті:
dev.forwww.com

Email: dmitriyribka@gmail.com

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *