블로그 로딩 속도 UP! (2) - CSS Sprite 사용으로 HTTP 요청 줄이기

2011. 3. 30. 03:45IT/Tistory Tips

글을 읽기 전에...

이 게시물에서는 태그 및 CSS에 대한 기본적인 이해가 있다는 바탕에 개별 이미지를 사용하던 방법을 CSS Sprite를 사용하는 방법으로 전환하는 내용만 간략히 다룰 것입니다. 각 태그 및 CSS 속성에 대한 설명은 생략합니다.

 홈페이지나 블로그 스킨을 구성하다 보면 이미지를 많이 사용하게 된다. 상단의 블로그 메뉴, 사이드 바, 검색 창, 각종 링크 등 많은 이미지를 사용하다 보면 각 이미지를 불러오기 위해 여러 번 HTTP 서버에 요청한다. 10개의 이미지를 사용하면 그 페이지를 정상적으로 표시하기 위해 10번 파일을 내려받는다. 이미지를 사용하지 않으면 그만큼 웹페이지 로딩 시간이 단축되겠지만, 이미지를 꼭 사용해야 할 상황도 있다. 이럴 때 웹 요청을 줄이는 방법이 CSS Sprite다.

 CSS Sprite의 개념은 아주 간단하다. 만약 4개의 이미지를 사용해야 할 때 4개의 이미지를 하나로 합친 다음 필요한 부분에 CSS에서 각 이미지 위치를 지정해서 불러오는 방식이다. CSS 중 background-position이라는 속성으로 사용할 이미지의 가로, 세로 위치를 지정하기만 하면 된다.

dark author author1.png sprite sprite.png
light author author2.png
dark home home1.png
light home home2.png

 예를 들어서 살펴보자. 네 개의 이미지가 있다. 진한 author와 Home, 연한 author와 Home. author와 Home에 각각 /'pəlp/ 블로그로 링크를 거는데 마우스를 올리면 연한 이미지가 진하게 바뀌도록 지정할 것이다. 만약 이 이미지를 세로로 합쳐서 오른쪽과 같이 만든 다음 하나의 이미지로 각 링크의 이미지를 지정한다면 어떻게 될까? 처음에 4개의 이미지를 사용하던 것을 하나의 이미지로 적용하면 네 번 나눠서 이미지를 내려받던 것이 한 번만 받게 되니 웹 요청이 1/4로 줄어든다.

 그럼 CSS Sprite를 위한 이미지를 만들어보자. 먼저 합칠 개별 이미지를 선택한 다음 아래의 웹사이트 중 하나를 방문한다.

Site 1 : ▶ spritegen.website-performance.org 방문하기
Site 2 : ▶ csssprites.com 방문하기


 spritegen.website-performance.org에서는 CSS Sprite로 만들 이미지를 zip으로 압축해서 사이트에 올린다. 그다음 [만들 방향]과 [출력 형식]을 선택한다. [만들 방향]은 이미지를 가로로 연결할지 세로로 연결할지 선택하는 옵션이다. [출력 형식]은 gif, png, jpg 중 CSS Sprite용 이미지를 어떤 형식으로 생성할지 정하는 옵션이다. [OptiPNG로 그림 압축]을 선택하면 기본적으로 64비트 png로 생성되는 파일을 상태에 따라 16비트나 32비트로 최적화해서 용량을 줄인다. 예를 들어 투명, 반투명 영역이 있으면 32비트, 단순한 이미지 파일이면 16비트와 같은 방식이다. 다른 설정은 굳이 조정할 필요 없다. 설정을 마치고 [Sprite Image & CSS 만들기]를 클릭하면 이미지와 CSS가 제공된다. [Sprite Image 내려받기] 단추를 클릭해서 생성된 이미지를 저장한다.

 csssprites.com에서는 개별 이미지를 올린다. 파일 선택을 클릭해서 하나씩 파일을 올리고 파일이 세 개 이상이라면 [Need more?] 단추를 누른 다음 다른 파일을 올린다. [Options]를 클릭하면 몇 가지 옵션을 확인할 수 있는데 특별히 조정할 필요는 없다. [Align elements]에서 가로(top), 세로(left) 이미지 방향을 지정할 수 있다. 설정을 마치고 [Generate!]를 클릭하면 이미지와 CSS가 제공된다.

 spritegen.website-performance.org의 결과다. CSS 규칙의 background-position 부분을 참고하고 이미지를 내려받는다.

 csssprites.com의 결과다. 역시 background-position 부분을 참고하고 Download Sprite PNG를 클릭해서 이미지를 내려받는다.

 이제 준비는 끝났다. 내려받은 파일과 background-position을 사용해서 실제로 CSS Sprite를 적용해보자. 예제로 링크를 연결하는 a 태그에 배경을 지정할 것이다. 보통 일반 이미지로 a 태그에 링크를 걸 땐 아래와 같이 사용한다. a 태그에 class를 지정하고 CSS에서 해당 클래스에 background와 display:block, 너비, 높이 속성을 지정한다. 결과는 아래와 같다.

<예제 1>
태그 및 CSS
<a href="http://circlash.tistory.com" title="블로그 대문으로 이동하기" class="img_ex1" target="_blank"></a>

<style type="text/css">
a.img_ex1{background:url(http://bit.ly/hYTUsK);display:block;width:60px;height:18px;}
</style>
결과
실제 적용 모습



 이번엔 CSS Sprite를 사용해서 링크 이미지에 마우스를 올렸을 때 진한 이미지가 연하게 바뀌는 것을 적용해보자. 앞에서 나온 background-position을 사용한다. 적용하는 방법은 다음과 같다.

<예제 2>
태그 및 CSS
<a href="http://circlash.tistory.com" title="블로그 대문으로 이동하기" class="img_ex2" target="_blank"></a>

<style type="text/css">
a.img_ex2{background:url(http://bit.ly/fMDiyI);display:block;width:60px;height:18px;}
a.img_ex2:hover{background-position:0 -18px;}
</style>
결과
실제 적용 모습



 위와 같은 방식으로 배경 이미지를 사용하는 태그에 CSS Sprite를 적용할 수 있다. 이번엔 여러 개의 링크에 일괄적으로 CSS Sprite를 사용해보자.

<예제 3>
태그 및 CSS
<div class="ex_css_a">
<a href="http://circlash.tistory.com" title="블로그 대문으로 이동하기" class="ex1" target="_blank"></a>
<a href="http://circlash.tistory.com" title="블로그 대문으로 이동하기" class="ex2" target="_blank"></a>
</div>

<style type="text/css">
.ex_css_a a{background:url(http://bit.ly/fMDiyI);margin:10px;display:inline-block;width:60px;height:18px;}
a.ex1{background-position:0 0;}
a.ex1:hover{background-position:0 -18px;}
a.ex2{background-position:0 -36px;}
a.ex2:hover{background-position:0 -54px;}
</style>
결과
실제 적용 모습


 일괄적으로 적용할 땐 .ex_css_a a { } 부분처럼 전체 영역(div class="ex_css_a")에 있는 모든 링크에 배경 이미지, display:block (또는 가로로 배열하려면 display:inline-block), 너비, 높이를 먼저 지정한다. 그 뒤에 개별 링크의 기본 배경(a.ex1, a.ex2)과 마우스를 올렸을 때 바뀔 배경(a.ex1:hover, a.ex2:hover)에 background-position 속성으로 이미지의 가로, 세로 시작 위치를 지정한다.

 CSS 스프라이트는 Google 등 유명한 포털 사이트나 다른 대형 사이트 대부분에서 메뉴나 아이콘을 구성할 때 사용한다. 작은 이미지를 여러 개 사용하는 개인 웹사이트나 블로그 스킨에 사용하면 웹 요청이 줄어 페이지 로딩 시간을 줄일 수 있다. 또 css의 background 속성을 사용할 수 있는 거의 모든 태그에 사용할 수 있다는 점도 장점이다.

  • 프로필사진
    Favicon of https://windlov2.tistory.com BlogIcon 돌이아빠2011.03.30 06:51 신고

    좋은 정보 감사합니다.^^!

  • 프로필사진
    Favicon of https://alllink.tistory.com BlogIcon 링크정보2011.03.30 14:46 신고

    처음에는 하나로 합치면 다운로드 받는 시간이 길어질 거라고 생각했는데, 실제 해보니까 여러개로 나눠져 있을 때보다 빨라지더라고요.
    트랙백 보내요.

    • 프로필사진
      Favicon of https://circlash.tistory.com BlogIcon circlash2011.03.30 16:09 신고

      네, 이미지 크기가 크지만 않으면 괜찮은 것 같아요^^ 트랙백 보냅니다~

  • 프로필사진
    알 수 없는 사용자2011.04.01 11:35

    그만큼 서버에도 부하가 덜 가니 빨리 처리가 되겠네요. 기억해 뒀다가 한번 써먹어 봐야겠습니다.
    좋은 하루 되세요~ ^^

    • 프로필사진
      Favicon of https://circlash.tistory.com BlogIcon circlash2011.04.01 21:10 신고

      네, 전 블로그 스킨에 이미지가 딸랑 네 개 밖에 없어서 적용할 일이 없지만, 이미지 여러 개를 사용할 땐 유용하겠더라구요. 각종 소셜 미디어 단추나 기타 이미지를 사용할 일이 생기면 적용해 보려구요.

      네포무크님도 즐거운 주말 보내세요^^

  • 프로필사진
    Favicon of https://quarker.tistory.com BlogIcon Uvan Osper2012.02.13 18:46 신고

    오옷... 감사합니다! 한번해볼려고 했던 팁인데 css 적용법을 몰라서 포기했었는데... 덕분에 잘 적용했어요^^ css 선택자 종류도 알아갑니다 (인터넷 검색으로 ; ㅋㅋ)

  • 프로필사진
    Favicon of https://quarker.tistory.com BlogIcon Uvan Osper2012.05.17 19:43 신고

    안녕하세요. 새 스킨을 만들다(랄까... 부족하지만)가 css sprite를 사용하던중에 문제가 생겼습니다. ㅠㅠ 제가 아직 html이나 css에 그렇게 잘 알지 못해서 ㅠㅠ.. 각각의 li 태그에 이미지를 주고 각각의 li를 css로 이미지의 좌표를 설정했는데, 그 중간에 width와 height가 li태그의 길이를 정해버려서 이상하게 나옵니다...일단은 li태그내에 내용없는 div태그로 어떻게 해결했는데말이죠 ㅠㅠ 해결방법은 없는지 묻고싶습니다. 그리고 .category-img1, .category-img2 {background-image:url(~)}형식으로 지정해도 css sprite가 먹히는지 (음.. 이미지를 각각 불러오지않고 한번만 이미지를 불러내서 두 태그에 적용하는지) 묻고싶네요. 귀찮게 해서 죄송하옵니다 ㅠㅠ

    • 프로필사진
      Favicon of https://circlash.tistory.com BlogIcon circlash2012.05.17 20:54 신고

      첫번째 이야기하신 부분은 li의 높이와 너비를 [사용할 이미지의 너비 + 글자 너비], [글자나 이미지 중 세로 길이가 더 긴 것의 길이]으로 설정해두고 그다음에 background-position으로 배경 그림 추가하고, 위치를 조정해주면 될 것 같습니다. width와 height가 li태그 길이를 정해버린다는게 잘 이해가 안가요, 원래 width와 height는 너비와 길이를 정하는 스타일인데 음,,, 질문 이해가 잘 안되요^^;;

      <!DOCTYPE html>
      <html>
      <head>
      <style>
      ul{list-style-type:none;margin:0;padding:0}
      li{background:url(http://bit.ly/fMDiyI) no-repeat;display:inline-block;width:150px;height:18px;padding-left:70px}
      .e2{background-position:0 -18px}
      .e3{background-position:0 -36px}
      </style>
      </head>

      <body>
      <ul>
      <li class="e1">
      <a href="circlash.tistory.com">Image 1</a>
      </li>
      <li class="e2">
      <a href="circlash.tistory.com">Image 2</a>
      </li>
      <li class="e3">
      <a href="circlash.tistory.com">Image 3</a>
      </li>
      </ul>
      </body>
      </html>

      그리고 CSS Sprite는 기본적으로 이미지를 한번만 요청해서 받아두고 나머지 CSS에 있는 background-position 스타일을 따라 이미 받아둔 이미지를 스타일에 맞게 표시하는 과정으로 진행됩니다. 음, 그러니까 원래 이미지를 한번만 불러내서 여러 태그에 동시에 적용하려고 사용하는 기술(?)입니다. 두번째 질문도 정확하게는 이해가 잘 안되지만,,, background를 여러번 지정하니 여러번 불러온다라고 생각 안하셔도 됩니다.~

      위에 있는 예제를 복사해서 메모장에 붙여넣기한 다음 파일 이름을 test.html로 저장하고 웹브라우저에서 열어보세요. CSS Sprite로 li 영역에 그림 + 문자가 들어가 있습니다.

      추가로 궁금한점 있으시면 다시 질문 남겨주시구요~

    • 프로필사진
      Favicon of https://quarker.tistory.com BlogIcon Uvan Osper2012.05.17 20:55 신고

      아 죄송합니다 ㅠㅠ 제가 읽어도 뭔가 이상하네요...
      width와 height는 길이와 높이인데 길이만 적었군요.
      두번째 질문은 생각하신게 맞습니다 ㅎㅎ.. 친절한 답변 감사합니다.

    • 프로필사진
      Favicon of https://circlash.tistory.com BlogIcon circlash2012.05.21 23:57 신고

      죄송이라뇨^^;;
      CSS Sprite 잘 활용하시길~

  • 프로필사진
    brian2012.11.09 12:21

    잘 보고 갑니다. 고맙습니다. :)

  • 프로필사진
    Favicon of https://breakdawn.tistory.com BlogIcon 올랑몰랑2014.03.18 15:23 신고

    좋은자료 올려 주셔서 감사합니당 ㅋㅋㅋ 고양이 너무너무 귀여워용 ㅋㅋ