블로그 이미지

카테고리

데꾸벅 (194)
Publisher (39)
Scripter (97)
Programmer (1)
Designer (30)
Integrator (18)
Pattern Searcher (4)
News (2)
강좌 및 번역 (3)

최근에 달린 댓글





처음 이바닥에 발을 들여놓은지 어언~ 십수년이 지나갑니다. 그러나 그때나 지금이나 웹페이지의 성능향상은 언제나 중요하게 생각되고 있습니다.
어느분이 방명록에 의뢰한 내용이 있어서 찾아보다가 우연히 찾게된 야후! 개발자 센터에서 정의한 웹사이트 최적화 방법입니다. 필요할것 같아 잠시 정리해봅니다.
참고적으로 이곳에서 더글라스 크록포트아저씨의 Ajax 최적화 방법도 들을수 있습니다. 관심있는 분은 참조하세요~
"웹사이트 최적화 기법" 이라는 책도 나와있다는걸.. 번역이 끝난후 알아버렸음돠.. ㅡ.,ㅡ;
High Performance WebSite에 가시면 웹사이트 최적화 기법들이 좀더 상세하게 설명되어 있으므로 확인하시기 바랍니다.
각 브라우저마다 페이지속도를 최적화하기 위해 브라우저의 성능평가나 지원가능한 라이브러리 또는 현재 표준지원여부등을 비교한 사이트도 함 들러보시길...



 

HTTP Request를 최소화하라!

End-User응답시간의 80%는 Front-end단에서 소요된다. 이러한 응답시간의 대부분은 보통 해당 페이지에 포함되어 있는 이미지, 스타일시트, 스크립트, 플래쉬등과 같은 컴포넌트를 다운로드 하는 것과 연관된다. 이러한 컴포넌트를 줄이는것이 웹페이지를 렌더링하는데 요구되는 HTTP Request의 수를 줄이는 한방법이며 좀더 빠른 웹페이지를 구성할수 있는 중요한 포인트이다.

웹페이지내의 컴포넌트의 수를 줄이는 한 방법으로 페이지 디자인을 간결하게 하는것이다. 그러나 좀 더 빠른 시간에 응답메세지를 받으면서 풍부한 컨텐츠(Richer Content)를 제공하기 위한 방법은 없을까? 여기 이러한 풍부한 디자인을 제공하면서 HTTP Request수를 줄이는 방법을 소개한다.

파일 묶기(Combined Files)

한개의 스크립트에 모든 스크립트를 묶어서 (데꾸벅 주: 순차적 다운로드 방법- head 영역에 script를 순차적으로 append시키는법) 사용하거나 하나의 CSS안에 다른 CSS를 묶는 식(데꾸벅 주: @import를 이용한 CSS import)으로 HTTP Request수를 줄이는 방법이다. 이러한 파일묶기 방법은 각각의 스크립트나 스타일시트가 서로다른 페이지에서 다양하게 사용될때는 조금은 무리가 있는 방법이기는 하나 캐쉬를 지원하므로 응답속도를 향샹시키는 하나의 방법으로 사용할수 있다.

CSS Sprites
CSS Sprites는 이미지 Request수를 줄이는 방법으로 사용한다. 하나의 이미지에 여러가지 백그라운드가 사용될때 이미지 조각들을 보여주는 background-image와 background-position 프로퍼티를 사용한다.
(데꾸벅 주: 하나의 버튼을 만들때 마우스오버, 마우스다운, 비활성화 상태의 버튼을 표시하자면 각각의 상태마다 버튼 이미지들이 필요한데 이러한 이미지들을 하나로 만들어서 한번의 Request를 이용해 CSS의 background-position을 사용하여 표현한다. 대부분의 Ajax framework이나 라이브러리들의 CSS를 보면 이렇게 사용하는곳이 많다. 디자이너들에게 추천해 줄만한 내용이다.  미남이의 이러쿵저러쿵 블로그를 참조하세요)

Image Maps
이미지맵은 하나의 이미지 않에 여러개의 이미지를 묶는 방법이다. 전체사이즈는 갔지만 HTTP Request의 수를 줄여줌으로써 페이지 로딩을 더 빠르게 한다. 이미지 맵은 navigation bar와 같이 페이지내에서 연속적으로 사용되는 이미지가 있다면 사용하는것이 좋다.(데꾸벅 예: 웹에디터의 메뉴들) 
페이지 네비게이션에 이미지맵을 사용하는것은 접근성면이나 컨트롤하기가 어려우므로 네이비게이션 영역에서는 추천하지 않는다.

URL Scheme를 이용한 데이타로써 인라인 이미지 사용
실제 페이지에서 이미지 데이타는 URL Scheme를 포함한 데이타로 사용된다. 이러한 것들이 HTML문서사이즈를 증가시킨다. 캐시된 스타일쉬트안에 이러한 인라인이미지를 포함시키는것은 HTTP Request와  웹페이지 사이즈를 줄여줄수 있는 한 방법이다. 인라인이미지의 경우는 아직 다른 브라우저에서는 지원하지 않고 있다.

(데꾸벅 주 : base64로 인코딩된 이미지 파일포맷으로 브라우저에서 재해석하여 렌더링 되므로 이러한 렌더링 타임을 줄이는것이 좋다.  IE8이나 다른 브라우저에서는 이미 base64 포맷으로 이미지를 사용할 수 있다.)

웹페이지를 설계할때 HTTP Request수를 줄이는 것에서 시작하라.
이것은 처음 방문한 사용자를 위해 성능향상을 위한 가장 중요한 가이드 라인이다.  Tenni Theurer씨의 블로그 포스트(Browser Cache Usage-Exposed!)에서 언급한것처럼 일일 방문자중 40~60%가 아무런 캐쉬가 없는 상태에서 여러분의 웹사이트에 방문한다. 이러한 첫번째 방문자를 위해 페이지를 설계하는것이 사용자경험을 좋게 만드는 중요한 키포인트이다. 




CDN(Content Delivery Network)을 사용하라!

사용자와 웹서버의 거리가 가까울수록 응답속도는 빨라진다. 사용자에게 좀더 빠르게 여러분의 컨텐트를 제공하고자 한다면 서버를 사용자들과 지리적으로 가까운쪽으로 분산하여 배포한다. 
(데꾸벅 주 : 서울에 사는 사용자에게 여러분의 컨텐츠를 제공하고자 한다면 서울에 있는 서버가 부산에 있는 서버보다 빠르다는 얘기이다. 그렇다고 서버를 여러군데 설치한다면 배보다 배꼽이 더 커지는 경우이다. 이럴 경우에는 CDN 을 이용하면 좀더 비용을 줄일수 있지만 그렇다고 CDN이 싸다는 얘기는 절대 아니다. 대부분의 돈많은(?) 포탈들의 경우 이러한 CDN을 사용하고 있고 속도가 빠른 웬만한 주요 벤더들의 국내사이트들은 대부분 CDN을 사용하고 있다고 보면 된다.) 


 

Gzip 컴포넌트 사용

참고 URL_1 : apache의 mod_gzip 설정하기
참고 URL_2 : gzip 압축테스트
참고 URL_3 : mod_gzip설치


스타일시트는 최상위에

 HTML specification 에 스타일시트는 페이지의 Head부분에 넣으라고 명백하게 기술되어 있다.
    " LINK태그는 HEAD태그에서만 사용할수 있고 몇개를 넣어도 상관없다. "



스크립트는 맨 밑에

동시에 컨텐츠를 다운로드 하는 문제가 발생한다.   HTTP/1.1 specification 에서는 브라우저는 하나의 호스트네임에서는 동시에 두개이상 컴포넌트를 다운로드 다운로드하지 않는다고 제시한다. 만일 여러분이 이미지를 여러개의 호스트네임으로 서비스한다면 여러분은 동시에 두개이상이 컴포넌트를 다운로드 받게 되는것이다.
스크립트가 다운로드 되는 동안 브라우저는 다른 컨텐츠를 다운로드 받지 않는다.
스크립트를 페이지 맨밑으로 보내지 못하는 경우도 있을 것이다 만일, 예를 들어 스크립트를 document.write를 써서 컨텐츠의 한 부분으로 넣는다면 해당 스크립트를 페이지 맨 밑으로 보내지 못할것이다.  당연히 스크립트의 scope 문제가 발생하게 된다.

대안으로는 defer 스크립트를 사용하는것이다.  DEFER 속성은 스크립트가 document.write를 포함하지 않는다는것을 가르키며 브라우저가 계속 렌더링 할수 있게 해주는 하나의 방법이였다. 불행히도 파이어폭스는 DEFER속성을 지원하지 않는다.

(요즘  자바스크립트 라이브러리들은 defer 속성 대신에 document.ready나, window.onload를 사용한다.)   



CSS Expressions 피하기

CSS expressions은 CSS Properties를 동적으로 사용하는 강력한 방법이기는 하나 위험하다. 인터넷 익스플러러 5 버전 이상에서 지원한다.  종종 개발할때 투명 PNG파일을 사용하기 위해 이와같은 expression을 사용하기도 하고, 이미지로된 콤보박스를 만들때 사용되기도 하지만 익스플로러를 제외한 다른 브라우저에서는 지원되지 않으므로 사용을 자제하는것이 좋다.



자바스크립트와 CSS는 외부파일로 작성 

속도향상 규칙의 많은 부분들이 외부자원을 어떻게 효율적으로 다루냐에 달려있다. 
실제로 외부파일들을 사용하면 페이지 로딩속도가 점차적으로 빨라진다고 한다. 왜냐하면 자바스크립트와 CSS는 브라우저에 캐쉬되기 때문이다.  HTML안의 자바스크립트와 CSS는 HTML이 요청될때마다 서버에서 다운로드 받게 된다.



DNS Lookup을 줄여라

DNS(Domain Name System)은  호스트이름을 IP 주소로 매핑시킨다. 전화번호부가 사람들의 이름과 전화번호부로 매핑되듯이 말이다.  만일 여러분이 브라우저에 techbug.tistory.com으로 타이핑한다면 DNS resolver는 서버 IP주소를 리턴받아 브라우저에서 접속하게 해준다. 
주어진 호스트네임을 IP주소로 바뀌는데 20~120 밀리초가 걸린다. 또한 브라우저는 DNS Lookup이 완료되기전에는 어떠한 것도 다운로드 받지 않는다.

 

 


프레임수를 최소화하라

Iframe은 부모문서에 HTML 문서를 삽입하는것이다. iframe이 어떻게 효과적으로 사용되는것인지 이해하는것이 중요하다.

<iframe> 써야 되는 이유:

  • 광고나 뱃지와 같은 로딩이 느린 3-party컨텐트들
  • Security sandbox
  • 동시에 다운로드되는 스크립트들

<iframe> 쓰지 말아야 되는 이유:

  • Costly even if blank
  • Blocks page onload
  • Non-semantic

 


 

DOM접근을 최소화하라

자바스크립트로 DOM요소에 접근하는것은 페이지응답속도를 느리게 한다. 대신에 여러분은

  • 접근했던 엘리먼트 참조를 캐쉬하라
  • "offline"노드들을 업데이트하고 그것들을 DOM트리에 추가하라
  • 자바스크립트로 레이아웃을 고정하는것을 피하라
더 자세한 정보를 원한다면 Julien Lecomte의 "High Performance Ajax Applications"를 참조하라 


이벤트 핸들러를 적절히 사용하라!

때때로 너무많은 이벤트 핸들러 때문에 페이지들의 응답이 늦는것 처럼 느껴진다.  이때는 이벤트 딜리게이션(event delegation)을 쓰는 것이 좋은 해결책이다. 만일 하나의 div에 10개 버튼을 가지고 있다면 각각의 버튼에 이벤트핸들러를 다는 대신에 div wrapper에 단 하나의 이벤트 핸들러를 사용하라. 

DOM tree로 어떠한 액션을 시작하기 위해 onload이벤트를 사용할 필요는 없다.단지 여러분이 원하는것은 DOM tree에 접근할수 있는 엘리먼트만 필요할 뿐이다. 또한 여러분은 이미지가 다운로드 되기를 기다릴 필요가 없다. 다만 모든 브라우저에서 사용할수는 없지만 DOMContentLoaded 이벤트는 onload대신에 사용할수 있을것이다. 여러분은 onAvailable 메쏘드와 같이 YUI 이벤트 유틸리티를 사용할 수 있다.
더 자세한 정보를 원한다면 Julien Lecomte의 "High Performance Ajax Applications"를 참조하라 

@import 보다는 <link>를 선택하라

 스타일태그는 항상 페이지 상단에서 정의한다. 다만 IE에서의 @import는 <link>태그를 페이지의 하단에 위치하는것과 같으므로 @import보다는 <link>를 사용하도록 한다. 
참고 사이트 : High Performace Web Site Blog



Filter사용을 피하라!

IE의   AlphaImageLoader 프로퍼티는  IE7미만 버전하에서 PNG이미지의 반투명한 문제를 해결하기 위한 목적으로 쓰는 filter이다.그러나 이러한 프로퍼티는 PNG이미지를 다운로드 받는동안 브라우저를 멎게(freeze) 만든다. 또한 이미지에 따른것이 아니라 똑같은 이미지가 여러개일 경우 각 엘리먼트마다 적용되므로 메모리 소비를 증가시킨다. 

가장 좋은 방법은 AlphaImageLoader를 사용하지 않는 방법이다. 굳이 사용하고자 한다면 IE7이상의 사용자에게는 적용되지 않도록  언더바(_) CSS hack을 사용한다. (_filter:AlphaImageLoader)



이미지를 최적화하라!

웹디자이너가 웹페이지 이미지들을 생성하고 난후 이러한 이미지를 웹서버에 올리기전에 해줘야 할 일들이 있다.
(데꾸벅 주:  웹디자이너는 포토샵으로 이미지 저장시 save as for web으로 저장한다.)

  • 이미지매직(imagemagick)을 이용하여   identify -verbose image.gif와 같이 GIF이미지들은 칼라수에 따라 사이즈를 설정할수 있다. (데꾸벅 주 : 포토샵으로도 indexed color를 설정했을때 선택가능)
  • 저장할때 GIF를 PNG로 변경하라. 가끔씩 개발자들은 PNG이미지가 브라우저마다 제한적으로 지원하는것 때문에 주저한다. 그러나 이것은 이미 오래된 얘기다 진짜 문제는 true-color PNG이미지의 alpha-tansparency때문에 그러한데, GIF이미지는 실제 true color가 아니며 다양한 투명이미지조차 지원하지 않는다. (데꾸벅 주: 가끔 anti-aliasing이 먹은 GIF이미지를 투명이미지로 만들때 테두리가 완벽한 투명성을 지원하지 않는다.) 
    이미지매직을 이용하면 convert image.gif image.png  과 같이 하면 된다.
  • pngcrush(데꾸벅 주: PNG이미지 커스터마이저)를 이용해서 최적화하라.
    pngcrush image.png -rem alla -reduce -brute result.png
  • jpegtran을 이용해서 JPG이미지를 최적화하라
    jpegtran -copy none -optimize -perfect src.jpg dest.jpg



이미지 크기의 원래사이즈를 적어라!

HTML 코드에 width와 height를 넣었다는 이유로 여러분이 원하는 것 보다 더 큰 이미지를 사용하지 말라! 만약 여러분이  <img width="100" height="100" src="mycat.jpg" alt="My Cat" /> 를 원한다면 그때 500x500px 를 작게 해서 넣는것 보다   100x100px의 이미지를 넣는것이 좋다.
(데꾸벅 주 : 이미지에 사이즈를 주는 것이 퍼포먼스 측면에서 좋습니다만, 원래 500x500px 이미지를 100x100px로 준다고 해서 퍼포먼스가 좋아지는것이 아니라 100x100px로 표기하였으면 100x100px짜리 이미지를 넣으라는 뜻입니다)



CSS Sprites를 사용하라

참조 : CSS Sprites Generator
번역본 보다 다른 블로거의 글이 좋아 인용합니다. 원본글은 아래에서 확인하삼~

웹 페이지의 첫 로딩 속도를 줄여주는 여러 방법들 중, 서버로의 요청 횟수를 초소화 하는 것은 웹 어플리케이션의 최적화 요소들 중에서도 중요한 덕목이자 실제 적용하기에도 아주 손쉬운 방법이다.

보통 웹 페이지에서 치장을 목적으로 사용되는 백그라운드 이미지들은 많이 사용될 수록, 자동적으로 그 요청 횟수도 늘어나기 마련인데, 이를 줄이고자 하는 목적으로 쓰이는 기법으로 CSS Sprites 기법이 있다.

간단하게, 아이콘이나 버튼과 같은 반복되서 표시되지 않는 그림들처럼 독립되어 있는 여러 그림들을 하나의 그림으로 합쳐놓고 CSS의 background-position을 보여질 요소에 따라 바꾸어서 표시하는 기법인데, 이렇게 하면 서버로의 요청 횟수를 줄여주면서 사이트 로딩 속도를 줄여주고 더불어서 내려받는 이미지의 크기까지 줄여줄 수 있는 부수적 효과를 얻을 수 있다.

이 곳 블로그에서도 오른쪽 옆구리 아래에 붙어있는 표딱지 그림들의 경우, 개별 이미지를 사용할 경우 웹 페이지에 표시하려면 모두 10 번의 서버 요청이 필요한데, CSS Sprites 기법을 써서 왼쪽에 보여지는 바와 같은 하나의 그림으로 모든 단추의 배경 그림들을 표시할 수 있었다.

실제 구현 방법은 아주 간단해서, unordered li들로 구성된 메뉴들의 각 li에 특정 id 값을 지정해 주고 a 태그 속에 있는 text node를 <span> 태그로 감싸고 난 후, 여기에 background image의 좌표 값을 표시될 해당 위치에 맞게 지정해 주면 모든 작업이 끝난다.

한 가지 주의가 필요했던 것은 text 때문에 배경 그림이 일부 가려지는 것을 막기 위해, <span>에 적용한 CSS의 padding-left 값을 li의 너비 만큼 주어서, 결과적으로 글자를 화면 바깥으로 밀어내어 표시되지 못하도록 하였다. 이렇게 해서, 마지막 CSS 적용 결과는 다음과 같다.

div#sidebar div#badges ul li {

    list-style-type: none;
    list-style-image: none;
    background-image: none;
    width: 80px;
    height: 15px;
    margin-bottom: 4px;
    overflow: hidden;
}

div#badges span {
    display: block;
    background-image: url(images/buttons-bg.png);  <-- 이미지는 한번만 요청한다.
    background-repeat: no-repeat;
    padding-left: 80px;
    cursor: pointer;
}

//각각의 이미지는 background-position으로 위치시킨다.
div#badges #vxhtml span {background-position: 0 -15px;}
div#badges #vcss span {background-position: 0 -30px;}
div#badges #wcag span {background-position: 0 -45px;}
div#badges #uni span {background-position: 0 -60px;}
div#badges #cc span {background-position: 0 -75px;}
div#badges #mac span {background-position: 0 -90px;}

출처 : 미남이's Blog




favicon.ico파일은 작고 캐쉬가 가능하게 제작하라!

favicon.ico는 여러분의 서버 root에 위치시키는 작은 이미지이다.  예를 들어 IE에서는 onload시 다른 컴포넌트를 요청할때 해당 컴포넌트가 다운로드 되기전에 먼저 로드된다. 여러분은 이러한 favicon.ico파일을 만들때 다음사항을 유의해서 작성하라.

  • 1K이하로 작게 제작하라   Imaemagick을 이용하면 작은 favicons이미지를 생성하게 해준다.
  • Expires header를 설정하라.


25K 이하의 컴포넌트로 제작하라!

이러한 제한은 iPhone이 25K보다 큰 컴포넌트를 캐쉬하지 못한다는 사실에 기인한다. 좀더 자세항 정보를 원한다면 Wayne Shea & Tenni Theurer의 "Performance Research, Part 5: iPhone Cacheability - Making it Stick" 를 참조하라.



하나의 Multipart 문서에 컴포넌트들을 묶어라!

(Pack Compoents into a Multipart Docuement)

전자우편의 첨부파일과 같이 Multipart문서에 컴포넌트들을 묶는것이 여러개의 컴포넌트들을 하나의 HTTP Request에 함께 전송하는데 도움을 준다.(HTTP requests는 비싸다는것을 반드시 기억하라)
여러분이 이러한 기술을 사용할때 사용자 Agent가 이러한 기능을 지원하는지 반드시 체크하라. iPhone은 이러한 기능을 지원하지 않는다. 







Post by 넥스트리소프트 데꾸벅(techbug)

댓글을 달아 주세요

  1. 2009.10.19 10:32 신고 아즈키  댓글주소  수정/삭제  댓글쓰기

    간만의 포스팅 잘 보고갑니다 훈훈하네요ㅎㅎ

  2. 2009.12.17 19:53 신고 행복한아빠  댓글주소  수정/삭제  댓글쓰기

    좋은 글입니다.
    그런데 @import가 성능측면에서 파일을 묶는 효과가 있는지는 확인해보는게 좋겠습니다.
    태클 아닙니다. 댓글입니다. ^^