Что такое ленивая загрузка изображений, как её можно реализовать всего в несколько строк, не подключая 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">..
Спасибо всем за прочтение, надеюсь было интересно :).