안녕하세요! 프론트엔드 개발자를 양성하는 강사입니다. 이번에 공부하실 내용은 웹 성능 최적화의 고전이자 기본기인 이미지 스프라이트(Image Sprites) 기법이네요!
과거부터 프론트엔드 실무에서 정말 많이 쓰였고, 지금도 여전히 널리 사용되는 기법입니다. 공식 문서의 내용을 하나도 빠짐없이, 이해하기 쉬운 구어체로 꼼꼼하게 번역해 드리고 실무 팁도 팍팍 넣어드릴게요. 자, 시작해 볼까요?
이미지 스프라이트(Image sprites)는 여러 개의 이미지가 필요한 수많은 웹 애플리케이션에서 널리 사용되는 기법입니다. 각각의 이미지를 별도의 독립된 파일로 불러오는 것보다, 이 이미지들을 하나의 커다란 단일 이미지로 묶어서 전송하는 것이 브라우저의 메모리와 네트워크 대역폭(bandwidth) 측면에서 훨씬 친화적이고 효율적입니다.
동일한 하나의 이미지 파일 안에서 개별 이미지들을 각각 구분해서 보여주기 위해 우리는 배경 위치(background-position) 속성을 사용합니다. 이렇게 하면 브라우저가 서버에 이미지를 요청하는 횟수(HTTP requests)를 획기적으로 줄일 수 있습니다.
💡 강사의 팁:
화면에 20개의 아이콘이 필요할 때, 이미지 20장을 각각 다운로드하면 브라우저는 서버에 20번의 요청을 보내야 합니다. 과거의 HTTP/1.1 환경에서는 한 번에 보낼 수 있는 요청 수에 제한이 있어서 이게 엄청난 병목(성능 저하)을 일으켰어요. 그래서 아이콘 20개를 1장의 이미지로 합쳐서 딱 1번만 요청하고, CSS로 좌표를 이동해가며 필요한 부분만 '잘라서' 보여주는 것이 바로 스프라이트 기법입니다!
참고 (Note):
만약 여러분의 서버가 최신 통신 규약인 HTTP/2를 사용하고 있다면, 사실 이미지들을 하나로 합치는 것보다 여러 개의 작은 이미지 요청을 그대로 사용하는 것이 대역폭 측면에서 더 유리할 수도 있습니다.💡 강사의 보충 설명: HTTP/2는 한 번의 연결로 여러 파일을 동시에 병렬로 다운로드할 수 있는 멀티플렉싱(Multiplexing) 기술을 지원합니다. 그래서 굳이 귀찮게 이미지를 하나로 합치지 않아도 빠르게 로딩될 수 있어요. 하지만 여전히 캐싱이나 렌더링 측면의 이점이 있어서 스프라이트를 쓰는 곳이 많으니 알아두셔야 합니다!
클래스가 tool-btn인 모든 아이템에 하나의 동일한 배경 이미지가 주어졌다고 가정해 보겠습니다.
.tool-btn {
background: url("myfile.png");
display: inline-block;
height: 20px;
width: 20px;
}
이제 배경 위치(background position)를 지정해 주어야 하는데요. 이 위치 값은 background 속성 안에서 url() 함수 바로 뒤에 두 개의 x, y 좌표 값으로 한 번에 추가할 수도 있고, 아니면 background-position이라는 별도의 속성으로 분리해서 추가할 수도 있습니다.
예를 들면 다음과 같습니다:
#btn1 {
background-position: -20px 0px;
}
#btn2 {
background-position: -40px 0px;
}
위의 코드가 어떻게 동작하는지 설명해 드릴게요. (이 요소들이 모두 tool-btn 클래스를 가지고 있어서 위의 이미지 규칙을 적용받고 있다고 가정합니다.)
ID가 btn1인 요소는 배경 이미지의 시작점(좌측 상단)을 왼쪽으로 20픽셀(-20px)만큼 밀어서 보여주고, ID가 btn2인 요소는 왼쪽으로 40픽셀(-40px)만큼 밀어서 보여주게 됩니다.
💡 강사의 팁:
"왜 좌표가 마이너스(-)인가요?"라고 헷갈려 하시는 분들이 많아요! 창문(요소의 크기 20x20)은 가만히 고정되어 있고, 그 뒤에 있는 커다란 풍경(배경 이미지)을 왼쪽이나 위쪽으로 끌어당겨야 우리가 원하는 다른 아이콘이 창문 틀 안에 들어오게 됩니다. 이미지를 왼쪽으로 당기니까 X 좌표가-20px,-40px이 되는 거예요!
이와 똑같은 원리를 응용하면, #btn:hover와 같은 가상 클래스를 타겟팅하여 마우스가 올라갔을 때(hover) 아이콘의 색상이나 모양이 바뀌는 효과도 아주 쉽게 만들 수 있습니다. (호버용 아이콘을 스프라이트 이미지의 다른 좌표에 미리 그려두고, 호버 시 background-position 좌표만 살짝 바꿔주면 됩니다!)
어떠신가요? 이미지 스프라이트의 핵심은 "큰 이미지를 한 번만 불러와서, width/height로 창틀 크기를 고정하고, background-position으로 배경을 요리조리 움직여 보여준다"로 요약할 수 있습니다.
혹시 이해가 잘 안 가는 좌표 계산이나, 가상 요소(::before, ::after)를 활용해 스프라이트를 실무에서 셋팅하는 방법도 추가로 연습해 보고 싶으신가요? 언제든 말씀해 주세요!