이번에는 웹 개발에서 이미지를 어떻게 다룰지에 대해 알아보고자 합니다.
엄청난 묘리를 다루는것은 아니지만, 이미지를 다루는데에 익숙하지 않은 분들에게 조금이나마! 도움을 드리고자 작성하였습니다.
피드백과 수정사항은 언제든지 환영합니다!
오늘날 웹 환경에서 가장 많은 데이터를 차지하는 것은 이미지입니다.
이제는 이미지를 사용하지 않은 웹 페이지는 사실상 없다고 봐도 무방할 정도이니까요.
이미지가 없는 블로그나 웹 페이지를 상상해보면.. 정말 지루하고, 보고싶지도 않을 정도죠. 그만큼 이미지는 사용자의 경험을 높이는 데에 정말 큰 역할을 합니다.
하지만 그만큼 많은 데이터를 사용하고, 서버와 네트워크에 부하를 주기도 합니다.
특히 최근들어 수많은 경쟁을 뚫고 나타나는 고성능 모바일 기기들은 한장에 수십 MB에 달하는 이미지를 생산해내기도 하죠.
이러한 환경에서, 이미지를 최적화하여 사용자 경험을 향상시키고 서버 부하를 줄이는 것은 매우 중요한 일입니다.
즉, 우리는 앱 전반에 걸쳐서 '용량은 작으면서도 화질은 좋은' 이미지를 사용하기위해 최적화를 해야합니다.
이를 다시 정리해보면 아래와 같습니다.
이 외에도 effort
와 같은 개념도 존재하지만, 여기서는 다루지 않겠습니다.
JPEG
는 손실 압축을 사용하는 이미지 포맷입니다.JPEG
퀄리티 값은 단순한 퍼센트가 아닌 수학적 공식에 기반한 '변수'이고, 이를 통해 파일의 크기와 품질이 결정됩니다.JPEG
의 손실 압축이 이러한 현상을 일으킵니다.PNG
설명에서 '자세히 알아보기: 로고와 텍스트에 PNG
가 적합한 이유'를 통해 더 이야기 해보겠습니다.CMYK
색상 모델을 지원하므로, 프린트용 이미지로도 사용할 수 있습니다.TIFF
등을 사용하는 것이 일반적이지만, 그런것을 사용하는 분이라면 이미 저보다 잘 알고 계실 것 같네요주된 용도: 중·소형 이미지에 적합하며, 중간 정도의 품질에서 파일 크기와 화질 간의 균형이 좋습니다. 웹 사진, 블로그 포스트 등에 주로 사용됩니다.
부적절한 용도: 알파 채널(투명도)이 필요한 이미지나 매우 높은 품질이 중요한 그래픽에는 적합하지 않다.
많은 분들이 이미지의 퀄리티를 퍼센트의 개념으로 오해하고 있습니다.
그러나, JPEG
의 설명 맨 첫줄에서 보셨듯이, JPEG
는 손실 압축을 사용하는 이미지 포맷입니다.
따라서 JPEG
는 원본 데이터를 모두 가지고있지 않고, JPEG
는 퍼센트의 개념으로 화질을 표현하는 것이 태생적으로 불가능합니다.
이를 좀 더 구체적으로 이야기하자면, 퀄리티를 70으로 내렸다가 다시 100으로 올린다고 해서 원본 이미지의 퀄리티를 되찾을 수 없으며, 심지어 다른 포멧의 이미지를 퀄리티 100으로 저장한다 해도 원본 이미지와 동일한 데이터를 가졌다고 보장 할 수 없다는 것입니다.
퀄리티를 100으로 설정할 경우, 파일 크기가 급격히 증가하지만 품질 향상은 느낄 수 없으며, 단지 더 비싼 모자이크된 이미지를 얻게 될 뿐입니다.
이러한 이유로, 우리는 적절한 타협점을 찾아야 합니다. 그리고 퀄리티 75가 바로 파일 크기와 품질의 균형을 맞춘 '스위트 스팟'입니다. 이 이상으로 퀄리티를 높인다 해도 대부분의 경우 파일의 크기만 커지고 품질 향상은 느낄 수 없습니다.
약간의 욕심을 부린다면 퀄리티 80 정도로 설정해도 괜찮을 테지만 그 이상은 과욕입니다.
PNG
는 비손실 압축을 사용하는 이미지 포맷입니다.PNG
는 텍스트나 로고와 같이 선명한 경계를 가진 그래픽에 적합합니다.주된 용도: 매우 큰 이미지, 품질이 중요한 이미지, 투명도가 필요한 그래픽에 적합합니다. 로고, 아이콘, 일러스트레이션 등에 주로 사용됩니다.
부적절한 용도: 파일 크기가 중요한 경우, 예를 들어 웹 페이지 로딩 속도가 중요한 경우에는 부적합하다.
앞서 설명한 것처럼, PNG
는 투명도를 지원하고, 이미지의 품질을 손상시키지 않는 비손실 압축을 사용하는 이미지 포맷입니다.
이러한 특성 때문에 PNG
는 로고나 텍스트와 같이 선명한 경계를 가진 이미지에 적합한데요, 이는 JPEG
와 비교해 본다면 좀 더 명확하게 이해할 수 있습니다.
계속 이야기했듯이, JPEG
는 손실 압축을 사용하는 이미지 포맷입니다.
특히 아래와 같은 DCT(Discrete Cosine Transform) 테이블과, 첨부하지는 않았지만 양자화 테이블(Quantization Table)을 사용하는데요, 덕분에 복잡한 이미지를 비교적 작은 용량으로 저장할 수 있습니다.
양자화 테이블은 굳이 꺼내지 않았지만, DCT 테이블은 하나의 꿀팁을 위해 꺼내왔습니다.
JPEG
는 이미지를 8x8 픽셀 블록으로 나누어 DCT를 적용하는데, 이 때 사용되는 DCT 테이블은 사실상 해당 블록의 픽셀을 뭉개버리는 것과 같습니다.
그런데 만약 이 뭉개짐이 텍스트나 로고와 같이 선명한 경계를 가진 이미지에 적용된다면, 이러한 경계가 흐릿해지거나, 뭉개지는 현상이 발생할 수 있습니다.
특히 여러 번 중복 저장을 하게 된다면, 이러한 현상은 더욱 심해질 수 있겠죠. 이게 바로 '디지털 풍화'라는 현상입니다.
위의 이미지를 보시면, JPEG
로 저장한 이미지는 텍스트의 경계가 흐릿해지고, 배경과 텍스트의 경계가 뭉개지는 현상이 발생합니다. 특히 글자 주변에 검은 점이 곳곳에 발생했네요.
특히 162x41 이미지의 경우, 단 2픽셀 차이이고 크기를 오히려 더 덜 줄였음에도 'ford'등의 부분에서 오히려 글자들이 더 흐릿해진 것을 볼 수 있습니다.
반면 PNG의 경우에는 비록 크기를 너무 줄인탓에 글자는 흐려졌을지언정, 주변부에 지저분한 잔상은 남지 않았습니다. 매우 깔끔한 배경을 보실 수 있죠.
이처럼 단색 배경이나 패턴의 반복 등, 단순한 이미지의 경우에는 앞서 말씀드린 '딕셔너리 기반 압축 알고리즘'의 특성상 매우 효율적인 압축률을 보여 오히려 JPEG
보다 용량이 작아질 수도 있습니다.
이러한 이유로, 로고나 텍스트와 같이 선명한 경계를 가진 이미지에는 PNG
가 적합하며, 이러한 이미지를 사용할 경우 JPEG
보다 더 나은 품질을 제공할 수 있습니다.
GIF
는 256색의 제한된 색상 팔레트를 사용하는 비손실 압축 이미지 포맷입니다.PNG
와 달리 반투명(부분적 투명도)은 지원하지 않습니다.주된 용도: 짧은 애니메이션, 간단한 움직임을 표현하는 그래픽에 적합합니다. 밈, 로딩 스피너 등에 주로 사용됩니다.
부적절한 용도: 색상이 복잡하거나 높은 품질이 요구되는 이미지에는 부적합 합니다. 정적인 이미지의 경우, 다른 포맷을 사용하는 것이 더 나은 품질과 효율성을 제공합니다.
WEBP
는 구글에서 개발한 이미지 포맷으로, JPEG
와 PNG의 장점을 모두 가지고 있습니다.JPEG보
다 약 30% 더 작은 파일 크기를 제공합니다.WEBP
를 비손실 고퀄리티로 사용할 경우, 오히려 PNG
보다 파일 크기가 커질 수 있습니다. 이는 비손실 압축이 특정 이미지에 대해 비효율적일 수 있기 때문입니다.WEBP
는 품질 값 65-75 정도에서 파일 크기와 화질 간의 균형이 가장 좋은 '스위트 스팟'을 갖습니다.GIF
보다 더 나은 대안이 될 수 있습니다.주된 용도: 파일 크기를 줄여야 하는 웹 환경에서 유용하며, 일반적인 웹 이미지를 대상으로 합니다. 중·소형 크기의 이미지에 적합합니다.
부적절한 용도: 대형 이미지나, 품질이 중요한 경우. 혹은 모든 사용자가 최신 브라우저를 사용하지 않는 환경에서는 부적합합니다.
AVIF
는 AV1
비디오 코덱을 기반으로 한 이미지 포맷입니다.AVIF
는 품질 값 50-60 정도에서 '스위트 스팟'을 갖습니다.CanIUse
기준) 브라우저에서도 지원 범위가 다를 수 있습니다.주된 용도: 파일 크기와 화질을 최대한 줄이고자 할 때 유용하며, 최신 웹 환경에서 이미지 최적화에 유리합니다. 중·소형 크기의 이미지에 적합합니다.
부적절한 용도: 대형 이미지나 품질이 매우 중요한 이미지, 혹은 모든 사용자가 최신 브라우저를 사용하지 않는 경우에는 부적합합니다.
앞서 말한것과 같이, 이미지의 크기를 적절히 조절하는 것이 이미지 최적화의 첫걸음입니다. 특히 최근 모바일 기기나 카메라의 발전으로 인해 대부분의 이미지는 과도하게 큰 해상도를 가지고 있고, 많은 사람들이 '이정도는 너무 작은것 아니야?'라고 생각하기도 합니다.
사실 벨로그에서는 둘다 똑같이 보여질겁니다.
하지만 대부분의 웹 환경에서 페이지가 실제로 그려지는 영역의 폭은 평균적으로 1200px 정도이며, 모바일에서는 400-600px 정도도 충분합니다. 정말 큰 경우에도 1920px 정도에 그치죠.
게다가 그 영역 안에 이미지가 가득 차야하는 경우는 더욱 드물구요.
또한 생각보다 사람들은 이미지의 해상도에 대해 그렇게까지 민감하지 않습니다.
물론 제품 판매 페이지의 상세보기 이미지나, 블로그 포스트의 특정 이미지 등에는 높은 해상도가 필요할 수 있겠지만, 그런 이미지는 직접 사용해보고 피드백을 받아보는 것이 가장 좋습니다.
그리고 또 하나 신경써야 할 부분은 브라우저의 렌더링입니다.
단순히 큰 이미지가 페이지에 존재하는 것만으로도 브라우저는 그 이미지를 렌더링하기 위해 메모리를 할당하고, 렌더링을 위한 작업을 수행합니다. 흔히들 말하는 버벅임이 발생하는 원인 중 하나가 바로 이러한 과도하게 큰 이미지의 크기 때문이기도 합니다.
이러한 이유로, 가장 먼저 해야 할 일은 이미지의 크기를 적절히 조절하는 것입니다.
또 한가지 고려해야 할 부분은 이미지 포맷입니다. 그리고 생각보다 신경써야 할 부분도 많죠.
이미지 포맷은 이미지의 특성에 따라 적절한 포맷을 선택하는 것이 중요합니다. 위에서 언급했던 각 포멧별 특성을 잘 알아두시고, 이미지의 특성에 맞는 포맷을 선택하는 것이 좋습니다.
그리고 꼭 이미지의 호환성도 고려해야 합니다. 세상에는 정말 수도없이 다양한 디바이스와 브라우저가 존재하며, 이들이 모두 같은 이미지 포맷을 지원하는 것은 아닙니다.
우리는 모든 이미지를 WEBP
로 처리할테야! 라고 생각하다가 엉뚱한 브라우저에서 CS문제가 생긴다면 참 골치가 아프실 겁니다.
그리고 포멧을 변경 할 때 반드시 필요한 과정이 바로 품질 조절입니다.
위에서 언급했듯이, 이미지의 특성별, 용도별로 수많은 선택지가 있습니다. 제가 제시한 스위트 스팟을 그대로 사용하셔도 좋겠지만, 각자 도메인에 맞게 테스트를 진행하시고, 사용자의 피드백을 받아보는 것이 가장 좋습니다.
이미지 최적화는 웹 개발자에게 꼭 필요한 기술 중 하나입니다. 앞으로 웹 상에서 이미지는 점점 많아질 것이고, 우리는 이를 더 많이 다뤄야 하겠죠.
하지만 이미지 최적화는 그렇게 어려운 일은 아닙니다. 명확한 답이 있지도 않구요.
제가 제시한 기준들이 마음에 들지 않으시다면, 다른 기준을 찾아보셔도 좋습니다.
어찌저찌 최대한 경험한 것들을 정리해보았습니다.
다른 분들이 이미지를 다루시는데에 조금이나마 보탬이 되면 좋겠네요.
언제든 피드백은 열려있습니다.
수정할 부분이나, 더 궁금하신 부분 등은 언제든지 댓글로 남겨주시면 감사하겠습니다!
한편으론 요샌 뭐 인터넷 다 빠르니까 좀 욕심을 부려보는게 아닐까 ㅋㅋ 뭐 60hz와 120hz를 구분하시는 분들도 계시니까 ㅋㅋㅋ