웹 이미지 효과 성능 대결
게시 됨: 2022-03-10브라우저가 그래픽 렌더링 기능을 지속적으로 개선함에 따라 브라우저 내에서 진정으로 디자인하는 능력이 점점 현실화되고 있습니다. 이제 몇 줄의 코드로 빠르고 극적인 시각적 효과를 얻을 수 있으며 많은 노력 없이도 일관성을 유지할 수 있습니다. 그리고 웹 개발의 대부분의 경우와 마찬가지로 종종 동일한 효과를 얻을 수 있는 많은 방법이 있습니다.
이 게시물에서는 가장 인기 있는 이미지 효과 중 하나인 회색조를 살펴보고 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에서 교차 출처 오류를 수정하려면 GitHub Pages 또는 Dropbox와 같은 교차 출처 리소스 공유(CORS) 친화적 사이트에서 이미지를 호스팅하고 crossOrigin="Anonymous"
를 지정해야 합니다. 데모는 라이브 예제를 참조하십시오.
<canvas>
를 사용하여 회색조 효과를 얻는 방법은 픽셀 값의 외부 값에서 빨강, 녹색 및 파랑 구성 요소를 제거하면서 광도 수준(밝기)을 유지하는 것입니다. 이를 수행하는 한 가지 방법은 다음과 같이 RGB 값을 평균화하는 것입니다. grayscale = (red + green + blue) / 3;
.

아래 예에서는 이미지 데이터에서 (R,G,B,a)
형식의 RGBa 값을 사용하고 있습니다. 빨간색 채널은 data[0]
, 녹색 채널은 data[1]
등입니다. 그런 다음 이러한 각 채널의 광도 수준(밝기)을 얻고 평균을 내어 이미지 회색조로 바꿉니다.
라이브 데모 – HTML5 캔버스
SVG 필터
SVG 필터는 Internet Explorer 및 Edge에서도 가장 광범위하게 지원되며 CSS 필터를 직접 사용하는 것만큼 (거의) 사용하기 쉽습니다. 동일한 filter
속성과 함께 사용할 수 있습니다. 사실 CSS 필터는 SVG 필터에서 파생되었습니다. 캔버스와 마찬가지로 SVG 필터를 사용하면 WebGL 음영을 활용하여 훨씬 더 복잡한 결과를 생성할 수 있으므로 2차원 효과의 평면을 초월할 수 있습니다.
SVG 필터를 적용하는 몇 가지 방법이 있지만 이 경우 일관성을 위해 CSS 필터 예제와 마찬가지로 배경 이미지에 filter
속성을 계속 사용합니다. SVG 필터의 가장 큰 차이점은 이 필터를 적절한 경로로 포함하고 연결하는 데 주의해야 한다는 것입니다. 이것은 우리가 사용하고 있는 요소 위의 페이지에서 SVG를 가져와야 함을 의미합니다 (템플릿 엔진과 include 문을 사용하여 더 쉽게 만들 수 있음).
라이브 데모 – 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); }
필터 성능
그렇다면 초기 렌더 성능과 관련하여 이것들은 어떻게 쌓이는가? 각각에 대한 테스트 페이지를 만들고 Chrome 47에서 WebPagetest 비교 기능을 사용했습니다. 각 테스트에서 약간 다른 결과가 나왔다는 점을 염두에 두고 전반적인 추세는 다음과 같이 요약할 수 있습니다.
CSS 필터, SVG 필터 및 CSS 혼합 모드 방법은 모두 비교적 유사한 시간 프레임에 로드됩니다. 때로는 SVG 필터가 CSS 혼합 모드보다 빠르며(항상 간신히) 그 반대의 경우도 마찬가지입니다. CSS 필터는 일반적으로 로드 속도가 가장 빠르며 <canvas>
는 항상 가장 느립니다. 이것은 가장 중요한 통찰력을 얻었습니다. <canvas>
는 이미지를 렌더링할 때 다른 방법보다 규칙적으로 뒤쳐져 있었습니다.
공정성을 위해 여러 이미지의 로드 시간도 비교하고 싶었습니다. 나는 (단 하나가 아닌) 각각의 10개 변환을 만들고 테스트를 다시 실행했습니다.
결과는 비슷했습니다(각 테스트마다 약간의 차이가 있음을 염두에 두십시오). 이 경우 CSS 필터는 0.1ms 느렸으며 CSS 필터, 혼합 모드 및 SVG 필터 간에 결과가 가장 빠른 방법에 대해 결정적이지 않음을 보여줍니다. 그러나 HTML5 <canvas>
는 이에 비해 눈에 띄게 뒤떨어졌습니다.
JavaScript 렌더링 및 페인트 렌더링 시간을 통해 페이지 로드 시간을 자세히 살펴보면 이러한 추세가 계속되는 것을 볼 수 있습니다.

필터 유형 | 렌더링 시간 | 칠할 시간 |
---|---|---|
CSS 필터 | 12.94ms | 4.28ms |
CSS 혼합 모드 | 12.10ms | 4.45ms |
SVG 필터 | 14.77ms | 5.80ms |
캔버스 필터 | 15.23ms | 10.73ms |
다시 말하지만, <canvas>
는 렌더링 시간과 페인팅 시간이 가장 긴 반면 두 CSS 옵션이 가장 빠르며 SVG가 중간에 있습니다.
이러한 결과는 의미가 있습니다. <canvas>
가 각 개별 픽셀을 가져와서 우리가 이미지를 전혀 보기도 전에 이에 대한 작업을 수행하기 때문입니다. 이것은 렌더링 시 많은 처리 능력을 필요로 합니다. 일반적으로 SVG는 벡터 그래픽에 사용되지만 래스터 이미지 효과를 다룰 때는 여전히 <canvas>
보다 SVG를 적극 권장합니다. SVG는 더 빠를 뿐만 아니라 DOM 내에서 다루기가 훨씬 쉽고 유연합니다. 일반적으로 CSS 필터는 SVG 필터보다 훨씬 더 최적화되어 있습니다. 역사적으로 SVG 필터에서 나온 바로 가기이기 때문에 브라우저에서 최적화되었기 때문입니다.
#필터 없음
필터를 사용하지 않는 것은 어떻습니까? 업로드하기 전에 사진 편집 소프트웨어에서 이미지를 편집하는 것과 전반적으로 가장 빠른 방법(CSS 필터 추가)을 비교했습니다(저는 Mac OS X에서 미리보기를 사용하여 채도를 제거했습니다). 이미지를 사전 편집할 때 테스트에서 일관된 0.1ms 성능 향상을 발견했습니다.
결론
이미지 필터는 웹에서 시각적 통일성과 미적 매력을 제공하는 재미있고 효과적인 방법입니다. 약간의 성능 저하가 있지만 브라우저의 빠른 디자인 이점과 상호 작용을 디자인할 수 있는 기회도 함께 제공됩니다.
간단한 이미지 효과의 경우 CSS 필터를 사용하십시오. 가장 광범위하게 지원되고 가장 간단하게 사용할 수 있기 때문입니다. 더 복잡한 이미지 효과를 보려면 SVG 필터 또는 CSS 혼합 모드를 확인하십시오. SVG 필터 효과는 채널 조작 기능과 feColorMatrix
때문에 특히 좋습니다. CSS 혼합 모드는 페이지에 겹치는 요소와 함께 정말 멋진 시각 효과도 제공합니다. SVG 내에서 유사한 혼합 모드(예: feBlend
)를 사용할 수 있지만, 혼합 혼합 모드에서 허용하는 것처럼 상호 작용이 SVG 자체에 관련되고 주변 요소와 관련이 없다는 점에서 CSS background-blend-mode
와 유사 mix-blend-mode
. 필터에 <canvas>
를 사용하지 마십시오.