Изображения занимают большую часть страницы и поглощают основную часть загружаемого трафика. Для ускорения загрузки необходимо проводить качественную оптимизацию, для уменьшения нагрузки на сервер. Один из вариантов ускорения рендеринга страницы - отложенная загрузка изображений с помощью технологий lazy load.
Есть несколько способов первоначального отображения изображения на странице:
- Размещение ссылки на изображение с последующим созданием объекта Image. В данном случае поисковики индексируют изображение по линку, и в то же время на странице первоначально отсутствуют дополнительные запросы к серверу
- Размещение изображение прозрачного пикселя с дальнейшей заменой параметра src. Тут необходимо использование утвержденных Google и Yandex значениями атрибута data, чтобы картинка попала в индекс. Тем не менее в данном методе сразу можно указать title и alt картинки
Это лишь способ первичного представления графики на странице используемые лично мной. Дальнейшие этапы технологии lazy load практически идентичны
Отложите загрузку скрытых изображений
Частая проблема в Google Speed Test связана именно с отложенной загрузкой скрытых изображений. Особенно явно данная проблема проявляет себя при тестировании скорости загрузки на мобильных устройствах. Рассмотрим несколько основных способов решения данной проблемы.
Оптимизация графики при подготовке контента
Первичную обработку графики лучше поручить дизайнеру или контент-менеджеру. По максимуму оптимизируйте изображения с помощью Adobe Photoshop еще на этапе подготовки контента. Картинки не должны превышать по ширине область в которой будут располагаться. При загрузке на сервер создавайте несколько версий изображений для мобильных и веб устройств, а так же уменьшенные превью. Обязательно используйте кэширование как на стороне сервера, так и на стороне клиента
Использование IntersectionObserver. Загрузка картинок при прокрутке страницы
Если на странице много графики - не обязательно загружать ее всю сразу, ведь пользователь может перейти к следующему разделу или уйти с сайта, так и не увидев большую часть изображений, а вы создадите лишнюю нагрузку на сервер. Лучшим решением будет постепенная загрузка картинок по мере прокрутки страницы и попадания графики в видимую часть экрана.
К сожалению интерфейс IntersectionObserver пока что не имеет полной поддержки браузерами, поэтому нужно осуществлять проверку и иметь возможность загрузить картинку альтернативным методом, например сравнением позиции верхней границы изображения и величины прокрутки страницы через прослушивание события scroll на теле документа. Конструктор интерфейса IntersectionObserver выполняет обратную функцию в момент, когда видимость отслеживаемого элемента пересекает определенное значение.
Свойства интерфейса IntersectionObserver
IntersectionObserver.root - определяет родительский элемент относительно которого будет определяться видимость отслеживаемого элемента. Если границы этого блока попадут в видимую область, условие будет считаться выполненным
IntersectionObserver.rootMargin - если свойство не указано, оно принимает значение "0px 0px 0px 0px". Определяет смещение видимой области - расширяет на указанные значения
IntersectionObserver.thresholds - массив порогов пересечения элемента с видимой областью
Методы интерфейса IntersectionObserver
IntersectionObserver.disconnect() - метод прекращает отслеживание всех элементов
IntersectionObserver.observe() - устанавливает на объект наблюдение изменения его позиции
IntersectionObserver.takeRecords() - возвращает массив элементов, которые попали в видимую область с момента последнего обращения к методу
IntersectionObserver.unobserve() - останавливает наблюдение за конкретным элементом
Скрипт lazy load. Ленивая загрузка изображений при прокрутке страницы
Ниже представлена полная версия скрипта lazy load, который осуществляет ленивую загрузку изображений по мере прокрутки страницы
document.addEventListener("DOMContentLoaded", function() { var Images= [].slice.call(document.querySelectorAll("img.lazyloading")); if ("IntersectionObserver" in window) { let lazyImageObserver = new IntersectionObserver(function(entries, observer) { entries.forEach(function(entry) { if (entry.isIntersecting){ let Image= entry.target; Image.src = Image.dataset.src; Image.srcset = Image.dataset.srcset; Image.onload = function(){ this.classList.remove("lazyloading"); delete this.dataset.src; delete this.dataset.srcset; } lazyImageObserver.unobserve(Image); } }); }); Images.forEach(function(Image) { lazyImageObserver.observe(Image); }); } else { // дополнительный метод который будет активирован при отсутствии IntersectionObserver } });
Опишем последовательность выполненных действий:
- Дожидаемся полной загрузки DOM документа, чтобы сразу отобразить пользователю текстовую часть страницы
- Создаем коллекцию всех изображений требующих ленивую загрузку. Если такие картинки отсутствует - прекращаем работу скрипта.
- Проверяем существование метода IntersectionObserver. В случае если метод отсутствует - применяем альтернативный способ ленивой загрузки изображений
- Во время прокрутки страницы определяем картинки, которые пересекли видимую область страницы и загружаем их. Для того чтобы подгружать изображения чуть раньше попадания в видимую область устанавливаем параметр rootMargin. За счет этого пользователь не должен заметить нашего эффекта
- Удаляем ненужные классы и атрибуты и перестаем отслеживать загруженную картинку за счет свойства unobserve