Вскрытие производительности веб-эффектов для изображений

Опубликовано: 2022-03-10
Краткое резюме ↬ По мере того, как браузеры постоянно улучшают свои возможности графического рендеринга, возможность по-настоящему проектировать в них становится все более реальной. Несколько строк кода теперь могут оказать быстрое и впечатляющее визуальное воздействие и обеспечить согласованность без особых усилий . И, как и в большинстве случаев в веб-разработке, часто существует множество способов добиться одного и того же эффекта. В этом посте мы рассмотрим один из самых популярных графических эффектов, оттенки серого, и оценим как простоту реализации, так и влияние на производительность холста HTML, SVG, фильтров CSS и режимов наложения CSS. Какой из них победит?

По мере того, как браузеры постоянно улучшают свои возможности графического рендеринга, возможность по-настоящему проектировать в них становится все более реальной. Несколько строк кода теперь могут оказать быстрое и впечатляющее визуальное воздействие и обеспечить согласованность без особых усилий . И, как и в большинстве случаев в веб-разработке, часто существует множество способов добиться одного и того же эффекта.

В этом посте мы рассмотрим один из самых популярных графических эффектов, оттенки серого, и оценим как простоту реализации, так и влияние на производительность холста HTML, SVG, фильтров CSS и режимов наложения CSS. Какой из них победит?

Дальнейшее чтение на SmashingMag:

  • Вскрытие производительности веб-эффектов для изображений
  • HTML5: факты и мифы
  • Эффективное изменение размера изображения с помощью ImageMagick
  • Умные методы оптимизации JPEG

Фильтры в Интернете работают как линза, наложенная на изображение. Они применяются к изображению после того, как браузер отрисовывает макет и начальную отрисовку. В поддерживаемых браузерах фильтры могут применяться индивидуально или накладываться друг на друга. Поскольку они могут быть применены в качестве модификации изображения после первоначального рендеринга и, вероятно, являются улучшением, фильтры изящно деградируют, просто будучи невидимыми в браузерах, которые их не поддерживают.

Еще после прыжка! Продолжить чтение ниже ↓

CSS-фильтры

Давайте начнем с самого простого метода создания эффекта оттенков серого: скромного, но мощного фильтра CSS.

нефильтрованное изображение птицы
Нефильтрованное изображение. (Посмотреть большую версию)

Чтобы добиться этого эффекта, мы добавляем одну строку CSS: filter: grayscale(1) . Этот фильтр обесцвечивает изображение и может использоваться с любым числовым или процентным значением от 0 до 1 (или от 0% до 100%). Примечание. В настоящее время фильтры для браузеров на основе WebKit должны иметь префикс -webkit- . Однако такое решение, как Autoprefixer, избавит от необходимости добавлять их вручную.

Живая демонстрация — фильтр CSS

 .cssfilter-gray { -webkit-filter: grayscale(1); background: url('img/bird.jpg'); filter: grayscale(1); }

Режим наложения фона

Режимы наложения CSS предоставляют бесконечное разнообразие вариантов комбинаций эффектов изображения. Существует два способа использования режимов наложения: свойство mix-blend-mode и свойство background-blend-mode .

  • mix-blend-mode — это свойство, которое описывает, как элемент будет смешиваться с содержимым позади него.
  • background-blend-mode используется для элементов с несколькими фонами и описывает взаимосвязь между этими фонами.

Мы будем использовать background-blend-mode: luminosity для наложения каналов яркости на серый фон в нашем примере, в результате чего получится изображение в градациях серого. Следует отметить, что порядок фона является постоянным: фоновые изображения всегда должны располагаться перед сплошными цветами или градиентным фоном, чтобы эффекты отображались должным образом . Цвет должен быть последним фоновым слоем. Это также защита от старых браузеров, которые не поддерживают background-blend-mode — изображение все равно будет отображаться без эффекта.

Единственная разница с режимами наложения и фильтром CSS заключается в том, что теперь у нас есть несколько фонов, и мы используем background-blend-mode: luminosity , который берет значения яркости из верхнего изображения (тестер птиц) и накладывает эти значения яркости на серый второй фон.

Живая демонстрация — режим наложения фона

 .cssfilter-gray { background: url('img/bird.jpg'), gray; background-blend-mode: luminosity; }

На данный момент это самый новый и, следовательно, наименее поддерживаемый вариант, хотя он по-прежнему хорошо работает в Chrome и Firefox и имеет частичную поддержку Safari. Примечание. Safari поддерживает все режимы наложения, кроме режимов наложения на основе HSL: оттенок, насыщенность, цвет и яркость.

Холст HTML5

HTML5 <canvas> обеспечивает массу гибкости, когда дело доходит до манипулирования изображениями, потому что у нас есть доступ к данным каждого отдельного пикселя (в частности, через canvasContext.getImageData ) и мы можем манипулировать каждым из них через JavaScript. Однако этот метод является наиболее сложным и сопряжен с наибольшими накладными расходами. Он также имеет несколько нюансов в вопросах кросс-происхождения из соображений безопасности.

Чтобы исправить ошибку перекрестного происхождения в Chrome, ваше изображение должно быть размещено на дружественном для совместного использования ресурсов (CORS) сайте, таком как GitHub Pages или Dropbox, и указать crossOrigin="Anonymous" . Смотрите живой пример для демонстрации.

Способ достижения эффекта оттенков серого с помощью <canvas> состоит в том, чтобы удалить красный, зеленый и синий компоненты из любого выпадающего значения в значении пикселя, сохраняя при этом уровень его светимости (яркости). Один из способов сделать это — усреднить значения RGB следующим образом: grayscale = (red + green + blue) / 3; .

В приведенном ниже примере мы используем значения RGBa в формате (R,G,B,a) в данных изображения; красный канал — это data[0] , зеленый канал — это data[1] и так далее. Затем мы получаем уровень яркости каждого из этих каналов (яркость) и усредняем их, чтобы превратить изображение в оттенки серого.

Живая демонстрация — холст HTML5

SVG-фильтр

Фильтры SVG имеют самую широкую поддержку (даже в Internet Explorer и Edge!), а также (почти) так же просты в использовании, как и фильтры CSS напрямую. Вы можете использовать их с одним и тем же свойством filter . Фактически фильтры CSS произошли от фильтров SVG. Как и в случае с холстом, фильтры SVG позволяют выйти за пределы плоской плоскости двумерных эффектов, поскольку вы можете использовать затенение WebGL для создания еще более сложных результатов.

Есть несколько способов применить SVG-фильтр, но в этом случае мы по-прежнему будем использовать свойство filter для фонового изображения, как и в примере с фильтром CSS для согласованности. Самая большая разница с фильтрами SVG заключается в том, что мы должны быть осторожны, чтобы включить этот фильтр и связать его с правильным путем. Это означает, что нам нужно импортировать SVG на страницу над элементом, в котором мы его используем (что можно упростить, используя механизм шаблонов и операторы включения).

Живая демонстрация — фильтр SVG

 <svg> <filter> <feColorMatrix type="saturate" values="0"/> </filter> </svg>
 .svgfilter-gray { background: url('img/bird.jpg'); -webkit-filter: url(#grayscale-filter); filter: url(#grayscale-filter); }

Производительность фильтра

Итак, как они складываются, когда дело доходит до начальной производительности рендеринга? Я создал тестовую страницу для каждого из них и использовал функцию сравнения WebPagetest в Chrome 47. Учитывая, что каждый тест давал несколько разные результаты, общую тенденцию можно резюмировать следующим образом:

Фильтр CSS, фильтр SVG и методы режима наложения CSS загружаются в относительно одинаковые временные рамки. Иногда фильтр SVG работал быстрее, чем режим наложения CSS (но всегда чуть-чуть) и наоборот. Фильтр CSS, как правило, загружался одним из самых быстрых, а <canvas> всегда был самым медленным. Это наиболее важное понимание, полученное. <canvas> регулярно отставал от других методов рендеринга изображения.

Справедливости ради я хотел также сравнить время загрузки нескольких изображений. Я создал десять представлений каждого (вместо одного) и снова запустил тесты:

Результаты были схожими (имейте в виду, что в каждом тесте были небольшие различия). Фильтр CSS в этом случае был на 0,1 мс медленнее, показывая, что между фильтрами CSS, режимами наложения и фильтрами SVG результаты для самого быстрого метода неубедительны. Однако HTML5 <canvas> заметно отставал в сравнении.

При более глубоком рассмотрении времени загрузки страницы с помощью рендеринга JavaScript и времени рендеринга рисования вы можете увидеть, что эта тенденция продолжается.

(Посмотреть большую версию)
Тип фильтра Время рендеринга Время рисовать
CSS-фильтр 12,94 мс 4,28 мс
Режим наложения CSS 12,10 мс 4,45 мс
SVG-фильтр 14,77 мс 5,80 мс
Фильтр холста 15,23 мс 10,73 мс

Опять же, <canvas> занял больше всего времени на рендеринг и больше всего времени на отрисовку, в то время как два варианта CSS были самыми быстрыми, а SVG оказался посередине.

Эти результаты имеют смысл, потому что <canvas> берет каждый отдельный пиксель и выполняет над ним операцию, прежде чем мы вообще сможем увидеть какое-либо изображение. Это требует много вычислительной мощности во время рендеринга. Хотя обычно SVG используются для векторной графики, я все же настоятельно рекомендую использовать их вместо <canvas> при работе с эффектами растрового изображения. Мало того, что SVG быстрее, с ним гораздо проще работать и он более гибкий в DOM. Как правило, фильтры CSS даже более оптимизированы, чем фильтры SVG, поскольку исторически они являются ярлыками, возникающими из фильтров SVG и, таким образом, оптимизированными в браузерах.

#нет фильтра

А если без фильтра? Я сравнил наш общий самый быстрый метод (добавление фильтра CSS) с редактированием вашего изображения в программном обеспечении для редактирования фотографий перед его загрузкой (я использовал предварительный просмотр в Mac OS X, чтобы удалить насыщенность). При предварительном редактировании изображения я обнаружил в своих тестах постоянное улучшение производительности на 0,1 мс:

Заключение

Фильтры изображений — это интересный и эффективный способ обеспечить визуальное единство и эстетическую привлекательность в Интернете. Имейте в виду, что они немного снижают производительность, но также имеют преимущества быстрого дизайна в браузере и возможности проектирования взаимодействия с.

Для простых эффектов изображения используйте фильтры CSS, так как они имеют самую широкую поддержку и самое простое использование. Для более сложных эффектов изображения воспользуйтесь фильтрами SVG или режимами наложения CSS. Эффекты фильтра SVG особенно хороши из-за их возможностей манипулирования каналами и feColorMatrix . Режимы наложения CSS также предлагают несколько действительно приятных визуальных эффектов с перекрывающимися элементами на странице. Вы можете использовать аналогичные режимы наложения в SVG (например, feBlend ), хотя они похожи на CSS background-blend-mode в том смысле, что взаимодействие относится к самому SVG, а не к окружающим элементам, как это позволяет mix-blend-mode . Просто не используйте <canvas> для фильтров.