Прогрессивная загрузка изображений и как её воспринимают пользователи
В последнее время часто встречаются статьи о том, как не показывать пользователям пустое место на странице, пока там не загрузилось изображение. Подобную технологию можно встретить на сайтах и в приложениях Medium и Facebook.
Когда я первый раз писал о загрузке изображений на Medium, мне было интересно реконструировать используемую этим ресурсом технологию. Я увидел её в действии, когда подключился к медленному интернету в самолёте. Первоначальная загрузка изображения с низкой детализацией и переход к конечному изображению после отложенной загрузки — отличная идея.
Этот приём улучшает восприятие веб-страниц пользователями?
Быстрый рендеринг всегда лучше медленного. Главное - вывести на экран хоть что-то, пусть это и не готовый контент.
Но уверены ли мы в этом? Изучив комментарии на Reddit, я нашёл много интересных (в том числе и негативных) комментариев. Вот два из них:
«Ненавижу сайты, которые показывают размытое изображение, пока не загрузилось основное. Приходится отводить взгляд и щуриться, чтобы читать дальше. Хочу найти способ отключить этот функционал».
— rocky1138, Hacker News
«Кто и когда решил, что если показывать сначала картинку низкого качества, загрузка будет казаться более быстрой? По мне, так все эти эффекты только отвлекают и выглядят ужасно. Загрузка уж точно не кажется более быстрой. Я все равно не могу понять, что на изображении, пока оно не загрузилось, есть там размытая заглушка или нет».
— dwb, Hacker News
Исследования о восприятии пользователями
Я решил найти научные исследования, которые могли бы подтвердить или опровергнуть позитивное восприятие таких приёмов. Но я не смог найти ни одного, которое бы подтверждало, что размытые изображения повышают «субъективную» скорость загрузки. В этот момент я вспомнил о прогрессивном JPEG.
Назад к основам: прогрессивный JPEG
Уже давно существует встроенная в изображения «технология прогрессивной загрузки». Хороший пример — прогрессивный JPEG.
Прогрессивный JPEG часто называют одним из лучших форматов изображений. Особенно для сайтов, на которые заходит большое количество пользователей с медленным подключением. Энн Робсон написала пост в поддержку прогрессивного JPEG ещё пять лет назад, подытожив его преимущества:
«Изображения в прогрессивном JPEG лучше, потому что они быстрее. Субъективная скорость важнее, чем настоящая скорость. Даже если мы загрузим на сайт слишком много изображений, то с помощью прогрессивного JPEG можно отобразить намного больше информации».
Прогрессивный JPEG кодирует изображения, разбивая их на несколько сканов. Первый скан выводит изображение с низкой степенью детализации, которая повышается, когда загружаются дополнительные сканы. Альтернатива прогрессивному — «базовый» режим, когда изображение загружается последовательно сверху вниз.

Базовое кодирование JPEG- изображения

Прогрессивное кодирование JPEG- изображения
Кодировка JPEG позволяет создавать и свои собственные скрипты сканирования. С их помощью можно сделать изображения, закодированные в гибридном режиме, совмещающем в себе свойства прогрессивного и базового JPEG.
С точки зрения пользователя, методы прогрессивной загрузки, такие как Blur-up и SQIP, похожи на прогрессивный JPEG: сначала браузер показывает изображение с низкой детализацией, а после загрузки заменяет его оригинальным.
Что интересно, большинство JPEG-файлов используют базовый режим. Прогрессивные JPEG-изображения составляют максимум 7% от всех файлов JPEG. Если прогрессивная кодировка субъективно ускоряет загрузку, почему прогрессивный JPEG не получил большего распространения?
Исследование
Мне удалось найти только одно исследование по теме, озаглавленное «Прогрессивный рендеринг изображений: добро или зло?»
«Однако, как и в случае с прогрессивным JPEG, подобный двухступенчатый рендеринг, в рамках которого размытое изображение внезапно становится резким, затрудняет восприятие. Поэтому мозгу приходится напрягаться, чтобы понять, что изображено на картинке».
Согласно результатам этого исследования, людям сложнее воспринимать прогрессивные JPEG, хотя на первый взгляд они и должны улучшать опыт пользователей.
Недавно я упомянул об этом исследовании в дискуссии, посвящённой LQIP («изображениям-заглушкам низкой детализации», от английского Low-Quality Image Placeholders). Сразу в нескольких ответах прозвучали сомнения в научной строгости исследования:
Многие ставили под сомнение состоятельность этой работы. Она идёт вразрез со всеми общепринятыми представлениями о пользе прогрессивного рендеринга, и пока что никто не представил второго исследования с похожими результатами. Нужно больше данных.
— Tobias Baldauf 🥠 (@tbaldauf) 9 декабря, 2017
Ограниченное и спорное исследование. Чтобы делать какие-либо выводы, нужны большие объёмы данных.
— Yoav Weiss (@yoavweiss) 9 декабря, 2017
Получается, что на данный момент существует только одно исследование, и то воспринятое с изрядной долей скепсиса. Возникает вопрос: можно ли измерить субъективную скорость загрузки с помощью существующих инструментов?
Измеряем субъективную скорость загрузки
Представим две следующих раскадровки, записанных с некого сайта:

Схема загрузки одного и того же сайта.
Пользователь субъективно воспринимает версию B как загружающуюся быстрее, чем версия A. Это происходит из-за того, что отдельные части страницы в версии B загружаются быстрее, чем в версии А.
В некотором роде это похоже на ситуацию с прогрессивными изображениями, только в более крупном масштабе — загрузить контент как можно быстрее, пусть и неокончательную его версию.
Чтобы оценить, как быстро загружается страница, сегодня используются такие показатели, как индекс скорости (Speed Index). Он измеряет процент того, насколько визуально закончена загрузка страницы. Чем ниже результат, тем лучше:

Формула индекса скорости
Изначально Speed Index измерял прогресс, сравнивая изменения в гистограммах каждого из основных цветов (красного, зелёного и синего). Этот метод называется «средняя разница гистограмм». Он помогает избежать ошибок, когда все элементы страницы могут одновременно сдвигаться на несколько пикселей в процессе загрузки. Подробно ознакомиться с работой алгоритма Speed Index можно в разделе документации, посвящённом измерению визуального прогресса.
Я решил испытать, как работает с заглушками низкой детализации тест WebPagetest:

Раскадровка, демонстрирующая степень визуальной завершённости в процентах.
Мы видим, что изображение загружается между 8 и 10 секундами. Размытая заглушка увеличивает процент завершённости с 75 до 83. Загрузка окончательной версии изображения доводит эту цифру до 93%.
Получается, что, согласно алгоритму Speed Index, заглушка вносит свой вклад в визуальную завершённость страницы. Видно и то, что заглушка не воспринимается как завершённая зона.
Speed Index — не единственный способ измерения скорости рендеринга страницы. В инструментах разработчика Chrome есть возможность запустить проверку производительности. Зайдите в меню Audits → Perform an audit → Run audit.
После выполнения проверка выдаёт вот такой отчёт:

Обратите внимание на размытую заглушку, которая затем превращается в финальное изображение.
Один из показателей проверки называется “Perceptual Speed Index” («Субъективный индекс скорости») и показывает значение 4,245. Что он означает? Возможно, это то же самое, что и Speed Index из теста WebPagetest?
Подход Speed Index с измерением схожести пикселей (та самая «средняя разница гистограмм») имеет свои недостатки. К примеру, он не учитывает визуальную схожесть фигур, цветов и объектов.

Четыре разных фигуры с одинаковым количеством чёрных и белых пикселей.
В большинстве случаев это не сильно повлияет на оценку визуальной завершённости — на практике Speed Index и Perceptual Speed Index в значительной степени совпадают.
«В ходе масштабных исследований (с использованием собранных WebPagetest видеозаписей более чем 500 страниц из мобильного рейтинга Alexa) мы увидели, что SI и PSI демонстрируют линейную корреляцию с коэффициентом 0,91», — Измерение скорости загрузки видимой части страницы при помощи Perceptual Speed Index (PSI)
Perceptual Speed Index («Субъективный индекс скорости»)
В документации к инструментам Google Lighthouse сказано, что PSI измеряется при помощи модуля Speedline. Он рассчитывает субъективный индекс скорости исходя из тех же принципов, что и обычный индекс скорости. Но при этом учитывает видимый прогресс загрузки, используя SSIM, а не разницу гистограмм.
SSIM («структурное сходство», от английского Structural Similarity) используется для измерения сходства двух изображений. Этот метод моделирует восприятие изображений человеческим глазом и учитывает, насколько похожи фигуры, цвета и объекты. Но на этом применение SSIM не ограничивается. Интересно использование структурного сходства при оптимизации сжатия изображений. Например, кодировка cjpeg-dssim использует максимальную степень сжатия jpeg и создаёт изображение с SSIM, близким к оригинальному.
В примере, приведенном ниже, показаны SVG-изображения, созданные в Primitive и проверенные в Image SSIM JS. Чем больше фигур мы используем, тем ближе оценка к изначальному изображению, где SSIM = 1.

Воспроизведение двух изображений при помощи треугольников. Чем больше фигур используется, тем ближе изображение к оригиналу.
Более новые альтернативы SSIM — это butteraugli (используется в кодеке Guetzli, Google’s Perceptually Guided JPEG Encoder) и SSIMULACRA.
Заключение
Довольно сложно воссоздать восприятие пользователя. Нам кажется, что лучше показать что-то раньше, пусть это будет и не окончательный вариант контента. Но некоторые пользователи с этим не согласны.
Мы — разработчики, и наша задача — измерять производительность. Это единственный способ, позволяющий понять, над чем конкретно нужно работать.
Преимущество прогрессивной загрузки изображений — возможность измерить её инструментами, основанными на восприятии пользователя. Они дают нам конкретные результаты. Они хорошо сочетаются с рабочим процессом, и никуда не исчезнут в обозримом будущем.
Мы, как разработчики, должны уделять больше внимания скорости загрузки сайтов. Хорошо, что у нас есть такие инструменты, как WebPageTest и Lighthouse, помогающие измерить эффективность прогрессивных методов загрузки изображений!