Загрузка видимых изображений
Допустим, у нас есть клиент с низкой скоростью соединения, и мы хотим сэкономить его трафик.
Для этого мы решили не показывать изображения сразу, а заменять их на «макеты», как тут:
<img src="placeholder.svg" width="128" height="128" data-src="real.jpg">
То есть, изначально, все изображения – placeholder.svg
. Когда страница прокручивается до того положения, где пользователь может увидеть изображение – мы меняем src
на значение из data-src
, и таким образом изображение загружается.
Вот пример в iframe
:
Прокрутите его, чтобы увидеть загрузку изображений «по требованию».
Требования:
- При загрузке страницы те изображения, которые уже видимы, должны загружаться сразу же, не ожидая прокрутки.
- Некоторые изображения могут быть обычными, без
data-src
. Код не должен касаться их. - Если изображение один раз загрузилось, оно не должно больше перезагружаться при прокрутке.
P.S. Если можете, реализуйте более продвинутое решение, которое будет загружать изображения на одну страницу ниже/после текущей позиции.
P.P.S. Достаточно обрабатывать вертикальную прокрутку, горизонтальную не требуется.
Обработчик onscroll
должен проверить, какие изображения видимы, и показать их.
Мы также можем запустить его при загрузке страницы, чтобы сразу обнаружить видимые изображения и загрузить их.
Код должен выполниться, когда документ загружен, чтобы у него был доступ к его содержимому.
Можно разместить его перед закрывающим тегом </body>
:
// ...содержимое страницы выше...
function isVisible(elem) {
let coords = elem.getBoundingClientRect();
let windowHeight = document.documentElement.clientHeight;
// верхний край элемента виден?
let topVisible = coords.top > 0 && coords.top < windowHeight;
// нижний край элемента виден?
let bottomVisible = coords.bottom < windowHeight && coords.bottom > 0;
return topVisible || bottomVisible;
}
Функция showVisible()
использует проверку на видимость, реализованную в isVisible()
для загрузки видимых картинок:
function showVisible() {
for (let img of document.querySelectorAll('img')) {
let realSrc = img.dataset.src;
if (!realSrc) continue;
if (isVisible(img)) {
img.src = realSrc;
img.dataset.src = '';
}
}
}
showVisible();
window.onscroll = showVisible;
P.S. В решении этой задачи есть также вариант isVisible
, который предварительно загружает изображения, находящиеся в пределах одной страницы выше/ниже от текущей прокрутки документа.