티스토리 뷰



들어가기 앞서…
 
ASP.NET 을 책을 통해 입문하게 되면, 처음 접하게 되는 것이 바로 서버 컨트롤 입니다. 그리고 MSDN 에서도 서버 컨트롤을 남용하면 웹 사이트의 성능을 저하시킬 수 있다고 말합니다. 이러한 서버 컨트롤을 사용하여 개발하는 방법을 ASP.NET 의 서버 모델이라고 합니다. ASP.NET 의 서버 모델은 웹 개발에 있어서 정말 편리하고 복잡한 처리를 단순화 시킵니다.
 
우리가 ASP.NET 을 처음 입문하면 포스트백(Postback) 이라는 용어를 듣습니다. 왜 기존의 서밋(Submit) 이라는 용어를 쓰지 않고, 독자적인 포스트 백(Postback) 이라는 용어를 사용할까요? 궁금하지 않으십니까?
 
ASP.NET 개발자들은 왜 서버 컨트롤이 웹 사이트의 성능을 저하시키는지 잘 알고 있는 사람은 드문 것 같습니다. ASP.NET 의 서버 컨트롤을 사용하는 서버 모델은 ASP.NET 의 성능을 저하시킵니다. 왜일까요?

 
ASP.NET 서버 모델이란?
ASP.NET 의 form 에 runat=”server” 를 사용하는 단일 Form 개발 방법입니다. 단일 Form 개발 방법은 서버 컨트롤을 사용할 수 있게 하며, 이러한 컨트롤에게 자동적으로 상태 유지 기능을 제공합니다.
 
HTML Form 모델이란?
ASP.NET, ASP, PHP, JSP 과 같이 다중 Form 을 이용하여 개발하는 기본적인 웹 개발 방법입니다.
 
MS MVC Framework != HTML Form 모델
HTML Form 개발 방법을 MS MVC Framework 과 동일시 하는 경우가 있는데, HTML Form 과 MS MVC Framework( 또는 MVC) 는 전혀 관련이 없습니다. 서버 모델에서도 MS MVC Framework (또는 MVC) 를 적용할 수 있으며, 윈폼 등 다양하게 적용 가능 합니다.
 
 
서버 컨트롤이 왜 느리죠?
 
서버 컨트롤은 ASP.NET 의 이벤트 기반의 프로그래밍을 가능하도록 하기 위해 독자적인 이벤트를 제공하고, 별도의 랜더(Render) 프로세스를 가집니다. 즉, 서버 컨트롤이 화면에 표시되기 위해 Render 메서드를 재정의(Override) 하여, 화면에 표시되는 HTML 을 생성합니다. 단순한 Label 컨트롤 마져 HTML Span 으로 랜더링되고, 많이 사용하는 그리드 관련 컨트롤은 table 태그를 사용하여 랜더링 합니다.
단순히 HTML Form 모델이라면 바로 스트림에 쓴 후 클라이언트에게 전달할 수 있지만, 서버 컨트롤은 이 과정에서 개별 컨트롤을 랜더링을 하게 됩니다.
 

[그림1] 서버 모델의 랜더링 과정
 
이 랜더링 하는 과정이 새발의 피보다 적은 시간이지만 웹 서버는 결코 혼자 쓰는 서버가 아니라는 점을 명심하세요.
 
이것은 서버 컨트롤을 사용하는 서버 모델의 근본적인 원인이 되어 추후에도 지속적으로 문제가 발생하게 됩니다.
 
 
서버 컨트롤은 적절하게 사용하면 되지 않나요?
 
ASP.NET 서버 모델에서 사용하는 환경에서 적절하게 사용한다는 판단은 팀 개발 환경에서 무척이나 주관적입니다. 이러한 판단은 개발자 주관에 맡길 수 밖에 없으며, 반드시 판단의 기준을 지키리라는 보장을 할 수 없습니다. 더 중요한 것은 적절하게 사용하는게 중요한 것이 아닙니다.
 
서버 컨트롤은 화면에서 사용한 개수도 중요하지만, 서버 컨트롤이 갖는 데이터가 어떤 것인지도 중요합니다. 단 하나의 서버 컨트롤만 사용하더라도 많은 양의 뷰 스테이트(ViewState) 를 갖게 된다면 더 이상 서버 컨트롤의 개수는 중요하지 않습니다.
 
 
뷰 스테이트(ViewState) 의 양이 많으면 왜 느리죠?
 
ASP.NET 의 서버 컨트롤은 상태 유지를 위해 ViewState 를 생성합니다. 뷰 스테이트는 HTML 로 랜더링될 때 히든 필드(Hidden Field) 에 그 값을 저장하고 클라이언트로 보냅니다.
서버 컨트롤을 랜더링 하고 또 상태 유지를 위해 추가적인 개별 컨트롤에 대해 객체 직렬화 과정을 거치게 됩니다.
 

[그림2] 상태 유지를 위한 뷰 스테이트(ViewState)
 
이러한 직렬화 과정이 소량의 데이터일 때 빠르다고 하더라도 데이터의 종류와 양에 따라 수십에서 수백 밀리 세컨드(Milliseconds) 가 느려집니다. 그리고 다시 한번 강조하지만 웹 서버는 혼자 쓰는 서버가 아니라는 점을 생각하면 이 과정이 누적되면 결코 짧은 시간이라고 장담할 수 없습니다.
 
 
컨트롤의 EnabledViewState 를 사용하지 않으면 되지 않나요?
 
특히 그리드 관련 컨트롤은 엄청난 양의 뷰 스테이트(ViewState) 를 생성합니다. 그리고 그리드안에 하위 컨트롤이 추가적으로 들어가있다면 거의 쥐약이나 다름없습니다. 그러므로 컨트롤에 대해 EnabledViewState 를 False 로 설정함으로써 ViewState 을 생성하지 않도록 지정할 수 있습니다.
 
하지만 이것은 근본적인 해결책이 될 수 없습니다. 그리드 컨트롤이 생성하는(기타 서버 컨트롤) HTML 은 컨트롤의 Render 메서드를 통해 HTML 코드를 생성한다고 하였습니다. 만약 tr, td 태그를 한 줄에 배치함으로써 네트워크 트래픽을 최소화 할 수 있지만 서버 컨트롤을 사용하면 이러한 HTML 코드를 직접적으로 제어할 수 없게 됩니다.
 

[그림3] 서버 컨트롤의 랜더링 코드를 제어할 수 없음
 
그리고 EnabledViewState 를 수동적으로 임의로 수정하게 되면 개발의 복잡성이 증가하고 유지 보수성이 저하됩니다. EnabledViewState 속성을 False 로 설정하면 더 이상 상태 유지 기능을 사용할 수 없기 때문에, 코드 비하인드의 로직 마저 수정되어야 합니다. 이러한 문제로 지속적인 성능 개선을 위해 여러 컨트롤에 거쳐 EnabledViewState 를 수정하게 된다면 개발의 복잡성과 유지 보수성 저하와 더불어 추가적인 리소스가 소요됩니다.
 
 
그럼 생산성을 포기하나요?
 
ASP.NET 은 이러한 상태 유지를 자동으로 처리해 줍니다. 그리고 서버 컨트롤의 이벤트 등을 사용하여 보다 빠른 생산성을 보장할 수 있다고 합니다.
 
정말일까요? 단지 이러한 이유 때문에 생산성이 향상됨을 느끼시나요?
 
서버 컨트롤의 그리드를 예로 들게 되면
 
1.     추가적인 디자인 작업이 소요됩니다.
디자이너에 의해 작업된 디자인 HTML 은 다시 한번 서버 컨트롤로 변환되어야 합니다. 차라리 디자이너에게 ASP.NET 의 서버 컨트롤 사용 방법을 알려주는 것이 편할 때도 있고, 실제로 이렇게 하기도 합니다. 하지만 디자이너에게 서버 컨트롤을 강요할 의무가 없으며, 디자이너가 서버 컨트롤을 사용하게 되면 디자이너의 원하는 디자인 작업이 힘들어 집니다.
 
특히 그리드 관련 컨트롤은 디자인된 HTML 을 그리드 관련 컨트롤로 옮기기 위해 더 머리가 아픕니다. 그리드 컨트롤이 개별적으로 랜더링 하기 때문에 1px 이 오차 나거나 디자이너가 원하는 디자인이 아닌 경우가 허다합니다.
 
2.     빌드 하기 전에 오류를 알아낼 수 없습니다.
랜더링 되는 그리드의 결과물이 조건에 따라 변경되어야 한다면, 대부분 그리드의 이벤트를 연결하여 작업합니다. 그리드에 랜더링 되는 상태 데이터를 가져오기 위해 추가적인 코드가 필요합니다.
그리고 이러한 방법은 코드를 다시 빌드하기 전에는 오류의 원인을 알 수 없기 때문에 추가적인 빌드 작업이 필요합니다.
이러한 빌드 작업은 웹 프로젝트의 어셈블리가 변경이 되며 IIS 를 리스타트 하도록 하여 웹 프로젝트 어셈블리가 다시 메모리에 적재됩니다. In-proc 세션을 사용하는 경우라면 세션마저 끊겨져 버립니다.
 
ASP.NET 의 서버 컨트롤 생산성 향상은 단편적이고 제한적인 경우에만 체감적으로 느낄 수 있으며, 상태 유지 또한 HTML Form 에서 그리 복잡한 작업은 아닙니다.
 
아래의 링크에 HTML Form 모델에서의 상태 관리 방법에 대한 글을 보시기 바랍니다.
 
 
그럼 성능 개선 방법은 없나요?
 
있습니다. 웹 사이트 최적화 기법을 통해 사용자의 최종 응답 속도를 향상시킬 수 있습니다. 만약 현재 운영하는 사이트의 성능이 문제가 된다면 다양한 튜닝 포인트를 통해 사용자의 응답 속도를 향상시킬 수 있습니다. 실제 이러한 개선 방안은 많은 서비스 또는 포털이나 도메인(Domain) 에서도 즐겨 사용하는 방법입니다.
 
하지만 이러한 방법은 서버 모델을 최적화하는 관점으로서 HTML Form 모델과 다시 비교하게 되면 더 나은 성능을 보장할 수 없고 근본적인 ASP.NET 의 성능과는 무관합니다.
 

[그림4] ASP.NET 서버 모델의 최적화 한계
 
이러한 최적화 기법을 통해 기존의 성능을 향상시킬 수 있지만, ASP.NET 의 성능 문제는 여전히 해결할 수 없습니다.
 
 
응답 속도가 향상 되었는데 또 뭐가 문제죠?
 
ASP.NET 의 서버 컨트롤은 사용의 편의성과 함께 자동적으로 상태 유지할 수 있는 크나큰 장점이 있습니다. 이러한 문제는 결국 뷰 스테이트(ViewState) 문제이고, 최적화 기법을 통해 기존 성능을 향상할 수 있습니다.
 
하지만 ASP.NET 의 상태 유지는 굉장히 위험한 요소를 가지고 있습니다. 이것은 ASP.NET 의 서버 모델은 단일 Form 밖에 사용할 수 없기 때문에 나타나는 현상입니다. 즉, 포스트 백(Postback) 이 원래 상태로 돌린다는 의미로써 이런 포스트 백(Postback) 처리를 하기 위해 상상할 수 없는 만행을 ASP.NET 이 저지르고 있습니다. 

ASP.NET 의 서버 모델과 HTML Form 모델의 랜더링된 HTML 코드는 상이하게 다릅니다.
 

[그림5] 서버 모델과 HTML Form 모델의 HTML 코드 비교
 
 
자! 뭐가 문제인 것 같나요?
 
서버 모델은 포스트 백(Postback)이 발생할 때마다 form 내에 존재하는 모든 요소를 다시 서버로 전송합니다. 즉, ViewState 가 전송되고 다양한 HTML 태그의 name 속성이 설정된 모든 요소들이 서버로 전송됩니다. ( 대부분의 서버 컨트롤의 명령이 처리되는 컨트롤은 name 속성이 포함됩니다 )
 
즉, 화면의 변경 전의 상태를 ViewState 에 기록하고, 변경 내용을 처리하기 위해 name 속성이 들어간 요소를 전송합니다. 즉, 변경 전, 변경 후 처리를 위해 엄청난 양의 데이터를 서버로 POST 로 전송합니다. 그리고 이러한 ViewState 를 다시 객체로 변경하기 위해 역직렬화 과정을 거치게 됩니다.

댓글