Во время загрузки сайта тег IMG занимает нулевой размер на странице. Затем при загрузке самого файла, блок раздвигает все элементы вокруг себя и занимает нужный размер. В этот момент, когда элементы страницы «толкаются» в стороны, происходит пересчёт макета в браузере.
Это требует времени центрального процессора на обсчёт новых позиций и размеров блоков и создаёт визуальный дискомфорт: страница дёргается, прыгает и скачет во время загрузки страницы. Также текст на странице начинает убегать вниз из-за появляющихся изображений, заставляя пользователя «ловить» строчку текста, которую он уже начал читать.
Эта статья — актуализация статьи англоязычного автора 2020 года и её расширение с учётом последних обновлений браузеров. Также материал структурирован от простого к сложному с более наглядными примерами, чтобы было увлекательней читать. Внутри есть интерактивные примеры, которые можно исследовать самостоятельно в браузере с помощью профайлера браузера.
Скачущие изображения, как они появляются?
Возьмём простую страницу с таким кодом:
<h1>Заголовок страницы</h1><p>Первый параграф страницы.</p><img src="jumping-image.jpg" /><p>Второй параграф. Остальное текстовое содержимое страницы.</p>
Во время загрузки такой страницы вы увидите следующую картину: после загрузки HTML кода страницы отобразится весь текст, затем загрузится картинка и второй параграф резко сместится вниз, освобождая место под появившуюся картинку.
Этот резкий скачок текста, вызванного появлением изображения, и называется «прыгающим изображением». Потому что резкое перестраивание структуры страницы и смещение крупных блоков выглядит как прыжок.
Чем они вредны скачущие изображения?
Скачущие изображения вредны по следующим причинам:
-
Масштабное смещение блоков требует от браузера пересчитывать структуру страницы. Эта операция может занимать сотни миллисекунд. На мобильных устройствах с их медленными процессорами эта проблема особенно актуальна. Страница может содержать десятки скачущих изображений, и тогда, из-за многократных пересчётов структуры страницы, суммарное время задержки может составлять секунды.
-
Визуальные рывки при загрузке страницы выглядят отталкивающе. Это подсознательно настраивает пользователя быть менее внимательным при изучении страницы или начать торопиться, что уменьшает вовлечённость пользователей. Плавная загрузка всегда предпочтительней.
-
Пользователи могут начать читать текст и по мере загрузки картинок весь текст начинает резко убегать вниз. Каждый был в такой ситуации, особенно на мобильных устройствах с их медленным интернетом. Ловить нужную строку текста, когда она от тебя убегает вниз экрана — то ещё удовольствие.
Основное решение проблемы
Наша задача — заранее зарезервировать место под будущую картинку. Для этого нужно просто указать у тега <img /> аттрибуты height и width. В CSS свойствах для этого элемента указываем width: 100%, а height: auto. Вот полный код:
<style>img { width: 100%; height: auto;}</style><h1>Заголовок страницы</h1><p>Первый параграф страницы.</p><img src="nit-jumping-image.jpg" width=800 height=600 /><p>Второй параграф. Остальное текстовое содержимое страницы.</p>
При таком коде происходит следующее:
-
Загружается HTML страница.
-
Согласно CSS свойству, ширина изображения растянется до 100% блока, в котором оно находится. При этом будут сохранены пропорции изображения 800х600 пикселей, указанные аттрибутах width и height.
Таким образом, не дожидаясь загрузки самой картинки, браузер сразу выделит то пространство, которое в будущем займёт изображение после загрузки. Страница не будет дёргаться, перестраиваться и прятать строки текста вниз во время загрузки.
Для тега <picure> аттрибуты width и height нужно указывать для тегов <source> (было внедрено в 2021–2022 годах) вот так:
<picture> <source width="400" height="600" srcset="./img-mobile.jpeg" media="(max-width: 1024px)" /> <source width="800" height="600" srcset="./img-desktop.jpeg" /> <img /></picture>
Альтернативные решения проблемы
Данные решения стоит применять лишь в очень специфических случаях, либо ради реализации совместимости со старыми браузерами. С точки зрения простоты понимания и дальнейшей поддержки кода, решение с аттрибутами width и height выигрывает во всём.
Трюк через padding-bottom (плохой вариант)
Этот трюк позволяет задать блок с заранее известным соотношением сторон. Изображение будет умещено в него.
.img-container { position: relative; padding-bottom: 56.25%; /* соотношение сторон 16:9 */ height: 0; overflow: hidden;}.img-container img { position: absolute; top: 0; left: 0; width: 100%; height: 100%;}
Трюк довольно старый, но использовать его не нужно, потому что:
-
Управление соотношением сторон изображения проходит сразу в нескольких местах: HTML коде, в нескольких местах CSS кода (когда нужно задавать разные картинки для разных экранов). Чем сильней разбросаны участки кода, выполняющих одну задачу — тем сложнее с ними работать.
-
Новички в веб-разработке могут не понять, суть техники и принцип её работы. Управлять высотой элемента через указание внутреннего отступа снизу может быть для них не очевидно.
-
CSS код имеет тенденцию к наращиванию, а не к переписыванию. В случае каких-либо визуальных правок или замены изображения специалист не осмелится менять существующее свойство padding-bottom, так как это может затронуть другие страницы сайта. Скорее всего, программист просто добавит новый класс для редактируемой картинки, переопределяющий свойство padding-bottom. Таким образом, кода будет становиться больше.
Свойство aspect-ratio (тоже плохой вариант)
Тут мы задаём соотношение сторон для изображения через специальное CSS свойство aspect-ratio.
img { width: 100%; height: auto; aspect-ratio: 16/9;}
Вариант лучше предыдущего только краткостью. Но все проблемы остаются такими же.
Экзотика через aspect-ratio: attr(width) / attr(height);
Опция задаёт соотношение сторон на основе аттрибутов width и height элемента.
img { aspect-ratio: attr(width) / attr(height);}
Опция вызвала бурные обсуждения: 100+ сообщений в Git и множество упоминаний в других темах, официальную дискуссию на 200+ сообщений представителями W3C, есть публикации на эту темы блогерами-экспертами, в том числе видео.
По факту оно работает так же, как аттрибуты width и height, но на чей-то вкус считается более «элегантным» с точки зрения красоты кода.
Для нас — прикладных программистов это означает только одно: нам просто надо знать ещё +1 способ решения задачи прыгающих изображений, чтобы не запутаться при встрече такой строчки кода.
Другие медиа компоненты: <video>, <iframe>, <canvas>, <object>
Теги <video>, <iframe>, <canvas>, <object> также поддерживают указание пропорций блока через аттрибуты width и height.
Неочевидные детали
-
Некоторые сайты скрывают содержимое до полной загрузки страницы, показывая лоад бар. Несмотря на то, что визуально мы не видим страницу, она всё равно отрисовывается браузером и на переобсчёт позиционирования блоков тратится процессорное время.
-
При использовании grid отображения все блоки в сетке подгоняются под один размер высоты и ширины. В таких случаях переобсчёт происходит только после загрузки 1 изображения в ячейке, а не каждого. Поэтому потери времени при переобсчёте страницы не так чувствительны в каталоге товаров интернет-магазинов, где элементы с картинками отображены с помощью техники grid.
-
Раз уж мы завели разговор о трате процессорного времени на пересчёт структуры страницы, то важно упомянуть, что подгрузка шрифтов вызывает самые большие всплески использования ЦПУ, поэтому подгружайте их как можно раньше, через директиву <preload>. Так, страница будет обсчитана только 1 раз, а не после каждой загрузки файла шрифта (если их несколько).
Протестируйте сами
Наглядную демонстрацию разницы между скачущими изображениями и фиксированными можно увидеть здесь.
Здесь доступен более нагруженный пример, демонстрирующий разницу в быстродействии. На медленных компьютерах будет заметен подлаг при появлении каждой картинки.
Рекомендуем самостоятельно замерить возросшее быстродействие страницы с помощью инструментов peformance аналитики браузера. Делается это следующим образом:
-
Открываете инструменты разработчика браузера клавишей F12.
-
Открываете вкладку профайлер.
-
Нажимаете кнопку «Записать и перезапустить» или сочетание клавиш Ctrl+Shift+E.
-
Ждёте загрузки страницы и нажимаете кнопку «Остановить».
-
Получаете детальную перфоманс аналитику.
Сервисы для проверки
Site Alarm — проверяет не только заполненность тегов width и height у картинок, а именно наличие скачущих изображений. Это значит, что он обнаружит неверные значения width и height, а также определит ситуации, когда отсутствие width и height не вызывает переобсчёт структуры страницы. Например, маленькие иконки редко нуждаются в width и height.
Google PSI — проверяет только заполненность тегов width и height. Грешит ложноположительными срабатываниями, так как проверяет только HTML код, а не отрисовку страницы.
ссылка на оригинал статьи https://habr.com/ru/articles/1080050/