본문 바로가기

.Net Technology/UI Performance

넥슨 사이트의 성능튜닝 - #1 성능 분석에 앞서서



안녕하세요~ 이번에 새롭게 튜닝요원으로 활동하게 된 HOONS입니다.성능에 관한 내용들을 어떤 방식으로 진행해야 보다 재미있고 흥미롭게 다룰 수 있을지 많은 고민을 했습니다. 고민 중에 선택한 방법이 국내의 사이트를 실례로 사이트를 직접 분석해보면 보다 재밌게 내용을 다룰 수 있다는 생각이 들어서 제목을 굉장히 건방지게 잡아 보았습니다.(-_-;) 여기서
 국내 사이트를 하나 선정하고 그 사이트에서 성능을 개선할 수 있는 요소들을 찾아볼 것입니다. 그리고 왜 적용해야 하고 어떻게 적용해야 하는지에 대한 내용을 살펴볼 것입니다. 


이번에 다루는 내용이 서버단이 아닌 UI 단의 튜닝이기 때문에 서버 단의 언어는 무관합니다. 하지만 필자가 닷넷에 각별한 애정을 가지고 있기 때문에 넥슨(
http://www.nexon.com/)을 선정하게 되었습니다. 이 웹 사이트는 당연히 IIS 기반의 웹 서버를 사용하고 있을 것입니다. 넥슨은 랭키닷컴의 순위 산출결과 국내 16위에 달하는 꽤 높은 페이지 뷰를 가지고 있는 사이트이고 당연히 성능에 민감할 사이트이기 때문에 분석 사이트로 선정하였습니다. UI 성능 튜닝에 대한 포스트에서는 간혹 C# 코딩과 ASP.NET 예제들이 첨부될 수 있습니다. 닷넷을 알고 있는 개발자라면 더 쉽게 이해할 수 있을 것입니다.

그럼 넥슨의 사이트를 분석해보기 전에 먼저 기본적으로 알고 있어야 하는 브라우저의 기본 동작에 대해서 살펴보도록 하겠습니다.


 
브라우저의 동작
 
이전 포스트에서도 설명했듯이 브라우저의 동작을 모니터링 하기 위해서 IE Watch(
http://www.iewatch.com/)라는 툴을 이용할 것입니다. 그리고 보다 자세한 정보가 필요하다고 생각될 경우 IBM Page Detailer(http://alphaworks.ibm.com/tech/pagedetailer)라는 툴을 이용할 것입니다. 
 
분석에 앞서서 아주 기본적인 브라우저 동작 개념을 설명하도록 하겠습니다. (혹시나 "아주 기본적인"에 상처 받는 개발자가 없기를 바라며-_-;) 넥슨의 홈페이지를 처음 방문할 경우 HTML뿐만 아니라 이미지, 스타일시트, 스크립트 등 모든 구성요소들을 자신의 PC로 다운 받게 됩니다. 다음 그림은 넥슨 홈페이지를 처음 방문했을 때 순차적으로 다운되는 모습을 보여주고 있습니다.


[넥슨 페이지를 처음 방문할 경우]
 
넥슨은 총 157번의 HTTP 요청을 만들고 있고 페이지 전체 크기는 약 1.1메가 정도 되는 것을 볼 수 있습니다. 가운데 상태코드(Status)를 보면 처음 302를 빼고 모두 200을 반환하고 있는 것을 볼 수 있을 것입니다. 동작 순서를 요약하자면, 브라우저는 처음에 HTML을 다운 받습니다. 위의 분석 결과를 보면 HTML을 다운 받는 시간은 약 0.234초가 소비된 것을 볼 수 있습니다. 이 시간은 바로 서버 단의 동작으로 봐도 무방합니다.(실제로 전달되는 시간을 빼야 하겠지만..) 그 뒤에 브라우저는 HTML을 분석하여 문서 위에서부터 차례대로 구성요소(플래쉬, 스크립트, 이미지등)들을 다운로드 하게 됩니다. 그렇게 모든 구성요소를 다운 받는 시간은 약 2.3초가 걸린 것입니다. 그리고 다운로드 된 구성요소들은 인터넷 임시파일 폴더에 저장됩니다. 여기서 중요한 것은 브라우저는 다운로드를 진행하면서 로딩되는 과정을 눈으로 볼 수 있게 지원하고 있다는 것입니다. 즉, 다운받는 즉시 브라우저에 표현해 주고 있다는 것입니다.(너무 당연한 거였나-_-;) 만약 그렇지 않으면 우리는 사이트가 굉장히 느리다고 생각할 것이다. 하지만 이런 로딩 화면을 지원하지 않게 될 경우가 있습니다. 그건 뒤에 포스트에서 다루도록 하겠습니다.
 
그럼 넥슨 페이지를 다시 한번 호출해 보면 어떻게 될까요? 이건 2번째 요청입니다. 즉, 처음 다운 받았던 여러 구성요소들은 이미 인터넷임시 폴더에 저장되어 있는 상태인 것입니다. 그럼 브라우저는 어떻게 동작되는지 살펴보도록 하겠습니다.
 


[넥슨 페이지를 두 번째 방문할 경우]
 
두 번째 방문할 경우 전체 응답시간이 1.5초로 줄어든 것을 볼 수 있습니다. 여기서 페이지 사이즈는 전달된 양과는 무관한 전체 구성요소의 합계를 나타내고 있습니다.(고물-_-;) 때문에 IBM 패킷 탐지기로 전체적으로 얼마나 다운받게 되는지 관찰해 보았습니다. 관찰해 본 결과 전체 사이즈는 0.16M 정도 되는 것을 확인할 수 있었습니다. 왜냐하면 이전에 이미 다운 받아 놓은 구성요소들이 인터넷 임시파일 폴더에 저장되어 있기 때문에 변경되지 않았다면 다시 다운로드 되지 않는 것이죠. 그런데! 왜 요청 수는 155로 줄지 않을 것일지 의문이 들 수 있을 것입니다. 그 이유는 브라우저는 구성요소가 디스크에 존재할 경우 이 요소가 변경이 되었는지 확인하는 요청을 보내게 되는 것입니다. 전문적인 용어로 Conditional Get Request라고 합니다.(역시 전문 용어를 써야 가오가 사는군요-_-;) 서버에게 수정되었는지 물어보고 만약 수정되지 않았다면 304 응답을 보내게 되고 수정되었다면 그 파일을 다시 보내주게 됩니다. 그렇기 때문에 HTTP요청은 반드시 일어나게 됩니다. 
위의 화면을 보면 페이지의 구성요소들의 상태코드들이 304라는 응답을 받는 것을 볼 수 있을 겁니다. 

브라우저는 요청–응답 방식으로 서버에 요청하고 응답을 받아 처리하게 됩니다. 브라우저는 다음과 같은 요청을 보내게 되고, 넥슨에서는 아래와 같은 요청들이 155번 일어났다고 보면 됩니다. 다음 요청은 넥슨의 로고가 수정되었는지 물어보는 요청입니다.
 

요청(Request)

브라우저->서버
GET /S2/Portal/Nexon/Nexon2007/image/global/logo_nx.gif HTTP/1.1
Accept: */*
Referer: http://www.nexon.com/main/page/nx.aspx
Accept-Language: ko
UA-CPU: x86
Accept-Encoding: gzip, deflate
If-Modified-Since: Fri, 25 Jan 2008 08:39:11 GMT
If-None-Match: "5f655c22d5fc81:6f"
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; ..
Host: s.nx.com
Connection: Keep-Alive
응답(Reponse)

서버->브라우저
HTTP/1.1 304 Not Modified
Date: Mon, 03 Mar 2008 12:12:44 GMT
Etag: "5f655c22d5fc81:6f"

 
필자는 이 요청-응답의 로그만 보아도 어떤 부분을 튜닝해야 해야 할지 대충 구상이 잡히고 있습니다. 튜닝을 위해서는 이 응답과 요청의 속성들을 이해하고 있어야 합니다. W3G 홈페이지(영문)를 방문해서 HTTP에 대한 스펙을 찾아보면 이 속성들에 대한 스펙을 정의하고 있는 것을 볼 수 있을 것입니다. 그럼 서버에서는 이 이미지가 최신 버전인지 어떻게 확인할까요? 이것은 HTTP 버전과 IIS의 설정에 따라 다릅니다. HTTP 버전은 1.0과 1.1이 존재하지만 대부분의 브라우저들은 1.1을 사용하고 있습니다. HTTP 1.1을 이용할 경우 서버는 Etag라는 것을 브라우저에게 발행하게 됩니다. Etag는 파일의 정보와 IIS 서버의 정보를 요약하여 만들어지는 파일의 고유한 아이디와 같은 값이라고 보면 됩니다. HTTP1.1을 이용할 경우 IIS의 서버에서 별다른 작업이 없을 경우 Etag값을 이용해서 파일이 서버의 내용과 일치하는지 확인하게 됩니다. 위의 요청(Request)을 보면 If-None-Mach를 보내게 되는 것을 볼 수 있습니다. (If-None-Match: "5f655c22d5fc81:6f") 그리고 만약 HTTP1.0을 이용하고 있을 경우 최근 수정 일을 통하여 파일을 비교하게 됩니다.( If-Modified-Since: Fri, 25 Jan 2008 08:39:11 GMT) 여기서 넥슨은 Etag를 사용하고 있는것을 볼 수 있는데 ETag는 성능을 떨어뜨리는 결정적인 문제를 가지고 있습니다. 이 부분의 내용은 다음 포스트에서 자세하게 살펴보도록 하겠습니다.
 

요약

넥슨 사이트의 성능을 올리기 위한 방법들을 간략하게 요약해 보겠습니다. 먼저 캐시의 만료기한을 지정하여 수정되었는지에 대한 확인 요청조차 만들지 않게 할 수 있습니다. 그리고 여러 가지 방법들을 적용하여 HTTP 요청을 최소화해야 합니다. 그리고 텍스트 파일들은 압축을 적용할 수 있지만 넥슨은 적용하지 않고 있습니다. 또한 굉장히 많은 스크립트들을 사용하고 있지만 최소화 하지 않았고 스크립트의 위치 또한 좋지 않습니다. 마지막으로 동시 다운로드를 이용하여 보다 빠르게 다운 받게 할 수도 있습니다. 등등 지금까지 필자가 언급한 내용들은 다음 포스트에서 천천히 살펴보면서 왜 적용해야 하고 또한 어떻게 적용해야 할지 살펴보도록 할 것입니다. 이 내용들을 적용할 경우 분명 2초에서 1초혹은 그 이상으로 웹 사이트의 성능을 끌어 올릴 수 있을 것입니다. (확신합니다_-_;)

그럼 다음 포스트에서는 간단하게 요약한 내용들을 보다 자세하게 분석해 보도록 하겠습니다.  
 




.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.