Альтернативний метод прихованої завантаження зображень технікою прогресивного поліпшення

18

Від автора: в майбутній статті про галерею я хотів би застосувати до зображень техніку прогресивного поліпшення, щоб створити живу, доступну презентацію високої якості.

Курка чи яйце

JavaScript не може гарантувати стовідсоткове приховування HTML-зображень до їх завантаження: якщо скрипт буде виконаний не вчасно, користувач може помітити спалахи на екрані – зображення завантажується і тільки потім ховається за допомогою JS. Якщо ж зображення завантажуються виключно через JS, а скрипти відключені або не спрацювали, тоді користувач побачить голу сторінку.

Зазвичай для вирішення цієї проблеми використовують комбінацію старих та нових технік: прозорий фільтр у форматі GIF розміром 1х1 px розміщується в атрибуті src, а справжнє зображення data — атрибуті.

Альтернативний метод прихованої завантаження зображень технікою прогресивного поліпшення

Потім JS замінює старе значення на нове, часто це робиться за події прокрутки:

var lazy = document.getElementsByClassName(‘lazy’);
for(var i=0; iОднак проблема блокування JS досі не вирішена. Для її рішення можна помістити даний зображення в тег noscript:

Альтернативний метод прихованої завантаження зображень технікою прогресивного поліпшення

Контент всередині тега noscript відображається лише у випадку, якщо JS не підтримується. Якщо JS працює, то GIF фільтри замінюються нормальними зображеннями, а контент noscript ігнорується. Тим не менш, у цього підходу є два мінуси:

Контент на сторінці повторюється два рази (перший в атрибуті data-src, другий в тезі noscript), що ускладнює роботу з кодом.

Немає фолбэка на випадок якщо JS підтримується, але в коді є помилка: контент noscript відображатися не буде, а зображення не заміняться на нормальні, т. е. сторінка залишиться порожня.

Інший спосіб

На вихідних я придумав інший спосіб. Він відмінно працює з одним припущенням, якщо браузера підтримує CSS анімацію. Я завантажував зображення на сторінку, але залишав їх невидимими, якщо JS був активний.

Зображення на сторінці розміщуються як зазвичай: у нашому випадку я обернув їх у блок DIV з двома класами; атрибут alt я залишив порожнім для спрощення коду:

Альтернативний метод прихованої завантаження зображень технікою прогресивного поліпшення
Альтернативний метод прихованої завантаження зображень технікою прогресивного поліпшення
Альтернативний метод прихованої завантаження зображень технікою прогресивного поліпшення
Альтернативний метод прихованої завантаження зображень технікою прогресивного поліпшення
Альтернативний метод прихованої завантаження зображень технікою прогресивного поліпшення
Альтернативний метод прихованої завантаження зображень технікою прогресивного поліпшення

Зображень встановлено властивість opacity 0:

.shuffle img {
width: 33%;
opacity: 0;
}

До зображень також причеплена анімація, яка зробить прозорість рівною 1 через 1 секунду: недостатньо, щоб хтось помітив, але достатньо, щоб JS підхопив роботу:

@keyframes reveal {
to {
opacity: 1;
}
}
.reveal img {
animation: reveal 1s 1s forwards;
}

Анімацію можна зробити більш витонченою, додавши послідовне плавне поява в CSS:

.reveal img:nth-child(1) { animation-delay: .5s; }
.reveal img:nth-child(2) { animation-delay: 1s; }
.reveal img:nth-child(3) { animation-delay: 1.5 s; }

JavaScript

Скрипт знаходить елементи з класом reveal за допомогою querySelector і видаляє їх з допомогою методу classList. Після цього анімація не спрацює:

var reveal = document.querySelector(«.reveal»);
reveal.classList.remove(«reveal»);

Зображення в посиланнях все ще доступні скрипту:

var revealedImages = reveal.querySelectorAll(«img»),

…тобто зображення завантажуються, але приховано, поки їх не покажуть з допомогою JS. В теорії можна не задавати opacity:0 через CSS, а робити зображення невидимими безпосередньо з JS:

Array.prototype.forEach.call(revealedImages, function(photo) {
photo.style.display = «none»;
})

Цей підхід трохи ризикований. Для його роботи ніщо не повинно блокувати JavaScript.

Результат

Якщо JS не підтримується, або не спрацював код, зображення з анімацією плавно з’являться через секунду – від JS версії майже не відрізняється (поява можна зробити послідовним, якщо додати CSS). Якщо JS працює, зображення будуть приховані до тих пір, поки скрипт не змінить їх.

Я тестував демо з допомогою інструменту зниження швидкості з’єднання до 2G, код працював відмінно. Єдине, що мені не подобається в CSS, це те, як він вибирає час: якщо хоч щось завадило виконанню JavaScript, анімація буде запущена відразу ж. Тим не менш, веб-сторінки, спроектовані за сучасними стандартами продуктивності, повинні нормально працювати. Сподіваюся, даний метод був вам корисний.