개발 환경에서는 잘 로드되던 작은 이미지 하나가 배포 환경에서는 로드되지 않는 문제가 있었다.
스타일적인 요소이기도 해서 img 태그의 src로 넘겨주지 않고, background로 처리해주고 있었는데 위와 같은 문제가 발생한 것이었다.
원인을 찾고 싶어서 크게 원인으로 예상되는 것을 뽑아두고, 찾아보았다.
원인 추측
1. 경로를 잘못 써주었다 !?
간혹가다 파일명이나 경로의 대소문자를 변경하고 바로 반영이 되지 않아 적용이 되지 않는 경우가 있기는 하다.
하지만 내가 사용한 이미지 경로에 대소문자만을 변경한 적도 없고, 절대 경로를 통해서 import 하고 있었기 때문에 상대 경로로 인한 문제도 아니었다.
2. 파일 형식에 문제인가?
이때 사용한 방식과 똑 ! 같은 방식으로 사용하고 있던 bacground-image들은 정상적으로 잘 로드되고 있었다.
그래서 그것과 비교하여 어떤 차이가 있어서 문제가 발생하는 것인지 좁혀보았다.
발견한 차이점은 png이냐 svg이냐의 차이였다.
그래서 파일형식을 변경해주자, 정상적으로 로드되기 시작했다.
찾았다 범..인.! !
이때 든 생각은 왜 svg 파일은 배포 환경에서 정상적으로 로드되지 않는 것인가? 였다.
이미지 파일 형식 종류
SVG 파일이 배포 환경에서 정상적으로 로드되지 않는 이유를 알아보기 전, 내가 주로 사용했던 파일 형식에 대해서 한 번 더 정리해보면 좋을 것 같아서 한 번 정리해보았다.
SVG (Sclable Vector Graphics)
이름에서도 드러나듯, 벡터 기반의 이미지 형식으로 수학적 도형 (점, 선, 다각형 등)으로 구성되어 있어 크기를 확대, 축소해도 화질이 떨어지지 않는다. 수학적 도형 간의 거리들을 수학적으로 계산하기 때문에 전체적인 비율에 따라서 적절하게 그려지기 때문이다.
장점
- 무한 확장 가능 : 해상도가 떨어지지 않는다.
- 파일 크기 작음 : 복잡한 이미지가 아니라면 파일 크기가 상대적으로 작다.
- 텍스트로 구성 : XML 기반으로 되어 있어 텍스트로 코딩이 가능하다.
단점
- 복잡한 이미지에 적합하지 않음 : 수학적 도형으로 구성하는 것이기 때문에 사진이나 복잡한 그래픽에는 비효율적이다. (오히려 크기가 커질 수 있다)
- 모든 프로그램에서 완벽하게 지원하지 않아 호환성이 떨어진다.
PNG (Portable Network Graphics)
PNG 파일은 흔히 투명도를 지원하는 이미지로 알려져 있고, 비손실 압축을 지원하는 래스터 이미지 파일 형식이다.
장점
- 비손실 압축 : 압축 과정에서 이미지 품질 손실이 일어나지 않는다.
- 투명도 지원 : 알파 채널을 통해 부분 투명 또는 완전 투명 배경을 만들 수 있다.
- 선명한 그래픽 : 텍스트나 간단한 그래픽에 적합하다.
단점
- 파일 크기가 큼 : 비손실 압축이기 때문에 JPG에 비해 큰 파일 크기를 가진다.
- 복잡한 이미지 : 큰 해상도의 사진을 저장하면 파일 크기가 굉장히 커진다. (이미지 로드에 시간이 걸리겠죠?)
** 래스터 이미지 파일 형식이란? 픽셀 단위로 이미지를 표현하는 방식으로 픽셀의 밀도( DPI )가 높을 수록 해상도가 높아지는 특징을 가지고 있다. (확대하면 밀도가 낮아져 해상도가 낮아짐)
** 알파 채널이란? 이미지에서 투명도를 표현하기 위한 추가적인 채널로, 이미지의 픽셀에 투명도 정보를 저장한다.
rgb + a(알파 채널) => rgba (빨간색의 강도, 녹색의 강도, 파란색의 강도, 투명한 정도 )
JPG (Joint Photographic Experts Group)
손실 압축을 사용하는 래스터 이미지 파일 형식이다. 압축률이 높아 파일 크기를 줄일 수 있지만 그 과정에서 이미지 품질이 손실될 수 있다. 확장자는 두 가지인데, jpg 또는 .jpeg 를 사용한다.
장점
- 효율적인 파일 크기 : 사진이나 그래픽을 작은 크기로 저장 가능
- 다양한 색상 지원 : 복잡한 색상 변화가 많은 이미지에 적합
단점
- 손실 압축 : 이미지 품질이 조금씩 손실되며, 반복적으로 저장하면 품질이 더 저하됨
- 투명도 지원 없음 : 배경 투명이 필요할 경우 PNG를 사용해야 함
요약
SVG | PNG | JPG |
단순한 이미지, 다양한 크기에서 품질 유지 | 복잡한 이미지, 투명도 필요, 품질 유지 | 작은 크기, 품질 노상관 |
svg 파일이 배포 환경에서 로드되지 않았던 이유가 뭘까
로드되지 않은 이유에 대해서 알아보다보니, svg 파일을 사용하기 위해서는 서버에서의 여러 설정이 동반되어야 한다는 사실을 알게되었다.
보안 및 CORS (Cross-Origin Resource Sharing)
svg 파일은 앞서 알아봤듯이, 텍스트 기반(XML) 파일이기 때문에 외부 리소스를 참조할 수 있으며 이는 보안 이슈를 유발할 수 있다. svg 파일이 외부 도메인의 리소스를 참조할 경우, CORS 정책에 따라 파일 로드가 차단될 수 있어, 배포 환경에서 CORS 정책을 올바르게 설정해야 한다.
이와 다르게 PNG 파일은 비트맵 이미지로, 서버에서 별도의 설정 없이도 기본적으로 지원하는 파일이고, 외부 리소스를 참조하지 않기 때문에 별도의 정책 설정 역시 필요 없다.
다른 곳에서 사용한 svg 잘 나왔는데..?
잠깐 ..!
하지만 위와 같은 이유 때문에 로드되지 않았던 것이라면 다른 svg 파일들은 그 동안 왜 잘 로드되었던 건지 궁금해졌다.
그 차이는 svg 이미지의 사용 방식에 있었다.
잘 로드되던 방식은 img 태그에서의 src로 svg 파일 경로를 import 해주었을 때이다.
이때의 img 태그는 SVG 파일을 외부 리소스처럼 취급하기 때문에 브라우저는 svg 파일도 다른 이미지 파일처럼 처리하고, 별도의 스타일링이나 스크립트를 실행하지 않고 단순히 이미지를 로드하고 표시한다.
-> 외부 리소스를 참조하거나 XML 파일 형식으로 처리하지 않는다는 것 ! (보안에 위협이 될 요소가 없음)
하지만, div 요소의 background로 svg 파일 경로를 import 해주었을 때는 svg 파일이 CSS 배경 이미지로 처리된다. 이렇게 처리하게 되면 SVG의 내부 구조나 외부 리소스에 대한 참조가 포함될 수 있다.
외부 리소스를 참조하거나 코드가 포함되어 있다는 것은 웹 보안의 (CORS 보안정책) 허점이 될 수 있기 때문에 이를 제한하는 과정에서 로드되지 않았던 것이다.
SVG로 외부 리소스를 참조하는게 왜 위험하지?
XML으로 이루어진 텍스트 기반 파일 형식인 SVG는 우리가 사용할 땐 단순한 이미지로 받아들이지만, 사실상 XML 기반의 문서로 동작할 수 있다.
XML 형식이라 할 수 있는 일
- JavaScript 코드를 포함할 수 있다.
- DOM 을 통해 웹페이지와 상호작용할 수 있다.
- 다른 XML 형식의 문서로 변환하거나, 서버에 악성 명령어를 주입할 수 있다.
이 외에도 XML 형식이기에 가능한 수많은 보안적 취약점들은 왜 서버에서 이 놈을 제한하는 지 이해하기에는 충분했다.
그리고 아주 복잡한 그래픽 요소를 포함한 SVG 파일을 렌더링할 때는 성능 문제가 발생하거나, 렌더링하는 과정에서 브라우저가 멈추거나 충돌하는 등의 문제를 일으킬 수 있다고 한다.
해결
파일 형식의 문제라는 것을 알게 되었고, png로 바꿔주자 정상적으로 이미지가 잘 로드되었다.
img의 src로 전해줄 때와 div의 background : url로 넘겨줄 때 브라우저가 다르게 받아들이고 참조한다는 것을 알게되어서 새로웠다.
역시, 요소의 태그들은 각각의 처리 방식과 역할이 있는 것 같다. 그리고 어떻게 사용할 것인지에 따라서 적절한 이미지 파일 형식을 선택해서 사용할 수 있는 지식이 늘어나서 즐겁다.
그럼 오늘 이만 ~!
안뇽 !
'🗂️ 개발 이모저모' 카테고리의 다른 글
카카오톡 공유하기를 원하는 대로 만들어보자 ! (with. 메시지 템플릿) (5) | 2024.09.29 |
---|---|
OAuth 과정을 알아보겠습니다 (with. 카카오) (4) | 2024.09.15 |
[타임세이버] query-key 줍다 지친 사람 여기 여기 붙어라 (with. query-key-factory) (0) | 2024.08.22 |
[FeedB] 무한 스크롤 구현 (with. App router & react-query) (0) | 2024.07.26 |
[FeedB] invalidateQueries가 동작하지 않았던 이유 (with. NextJS) (0) | 2024.07.05 |