고성능 ASP.NET 응용 프로그램 개발

이 항목의 지침에서는 ASP.NET 웹 응용 프로그램의 처리량을 극대화하기 위해 사용할 수 있는 기술을 설명합니다. 지침은 다음 단원으로 구성되어 있습니다.

  • 페이지 및 서버 컨트롤 처리

  • 상태 관리

  • 데이터 액세스

  • 웹 응용 프로그램

  • 코딩 작성 방법

페이지 및 서버 컨트롤 처리

다음 지침에서는 ASP.NET 페이지 및 컨트롤 작업을 효과적으로 수행하는 방법을 제안합니다.

  • 서버로의 불필요한 라운드트립 방지   ASP.NET 서버 컨트롤을 사용하거나 다시 게시 이벤트 처리를 수행할 필요가 없는 경우가 있습니다. 예를 들어, ASP.NET 웹 페이지에서의 사용자 입력 확인 작업은 해당 데이터가 서버로 제출되기 전에 클라이언트에서 수행할 수 있습니다. 일반적으로 정보를 서버로 전달하여 확인하거나 데이터 저장소에 기록하지 않아도 되는 경우 서버로의 라운드트립을 발생시키는 코드 사용을 방지하면 페이지 성능과 사용자 경험이 향상됩니다. 클라이언트 콜백을 사용하여 전체 라운드트립을 수행하는 대신 서버에서 데이터를 읽어올 수도 있습니다. 자세한 내용은 ASP.NET 웹 페이지에서 다시 게시하지 않는 클라이언트 콜백을 프로그래밍 방식으로 구현을 참조하십시오.

    사용자 지정 서버 컨트롤을 개발하는 경우, 이러한 컨트롤을 ECMAScript(JavaScript)가 지원되는 브라우저에 대한 클라이언트측 코드로 렌더링할 것을 고려해 보십시오. 이런 방법으로 서버 컨트롤을 사용하면 정보가 웹 서버로 보내지는 횟수를 많이 줄일 수 있습니다. 자세한 내용은 사용자 지정 ASP.NET 서버 컨트롤 개발을 참조하십시오.

  • 페이지 개체의 IsPostBack 속성을 사용하여 불필요한 라운트트립 처리 방지   서버 컨트롤 다시 게시 처리를 수행하는 코드를 작성하는 경우 다시 게시할 때마다 실행되는 대신 처음으로 페이지가 요청된 경우에만 실행되도록 코드를 작성할 수 있습니다. 서버 컨트롤 이벤트에 대한 응답으로 페이지가 생성되는지 여부에 따라 조건부로 코드를 실행하려면 IsPostBack 속성을 사용합니다.

  • 필요한 경우에만 서버 컨트롤 뷰 상태 저장   자동 뷰 상태 관리를 사용하면 코드를 작성하지 않아도 서버 컨트롤에서 라운드트립에 대한 속성 값을 다시 채울 수 있습니다. 그러나 서버 컨트롤의 뷰 상태는 숨겨진 폼 필드로 서버에 전달되거나 서버로부터 전달되기 때문에 이 기능은 성능에 영향을 줍니다. 뷰 상태가 언제 도움이 되고 언제 페이지의 성능에 방해가 되는지 알아 두는 것이 좋습니다. 예를 들어, 모든 라운드트립에서 서버 컨트롤을 데이터에 바인딩하는 경우 컨트롤의 값이 데이터 바인딩 중에 새 값으로 바뀌기 때문에 저장된 뷰 상태는 유용하지 않습니다. 이 경우 뷰 상태를 사용하지 않으면 처리 시간이 단축되고 페이지 크기가 줄어듭니다.

    뷰 상태는 모든 서버 컨트롤에서 기본적으로 사용됩니다. 뷰 상태를 사용하지 않으려면 다음 DataGrid 서버 컨트롤 예제에서와 같이 컨트롤의 EnableViewState 속성을 false로 설정합니다.

    <asp:datagrid EnableViewState="false" datasource="..." 
       runat="server"/>
    

    @ Page 지시문을 사용하여 전체 페이지에서 뷰 상태를 비활성화할 수도 있습니다. 이것은 페이지에서 서버로 다시 게시하지 않을 때 유용합니다.

    <%@ Page EnableViewState="false" %>
    

    참고

    EnableViewState 특성은 @ Control 지시문에도 지원되며, 사용자 정의 컨트롤에 대한 뷰 상태의 사용 여부를 지정하는 데 사용됩니다.

    페이지의 서버 컨트롤에서 사용하는 뷰 상태의 크기를 분석하려면 @ Page 지시문에 trace="true" 특성을 사용하여 페이지 추적을 사용합니다. 추적 출력에서 Control Hierarchy 테이블의 Viewstate 열을 확인합니다. 추적 및 추적 사용 방법에 대한 자세한 내용은 ASP.NET 추적 개요을 참조하십시오.

  • 특별히 해제할 이유가 없는 경우 버퍼링을 그대로 유지   ASP.NET 웹 페이지 버퍼링을 사용하지 않으면 성능이 크게 저하됩니다. 자세한 내용은 Buffer 속성을 참조하십시오.

  • Server 개체의 Transfer 메서드나 페이지 간 게시를 사용하여 동일한 응용 프로그램의 ASP.NET 페이지 간에 리디렉션할 수 있습니다.   자세한 내용은 사용자를 다른 페이지로 리디렉션을 참조하십시오.

상태 관리

다음 지침에서는 효율적인 상태 관리 방법을 제안합니다.

  • 사용하지 않는 경우 세션 상태 비활성화   모든 응용 프로그램이나 페이지에 사용자별 세션 상태가 필요한 것은 아닙니다. 필요하지 않은 경우 세션 상태를 비활성화해야 합니다. 페이지의 세션 상태를 비활성화하려면 다음 예제와 같이 @ Page 지시문의 EnableSessionState 특성을 false로 설정합니다.

    <%@ Page EnableSessionState="false" %>
    

    참고

    페이지에서 세션 변수에 액세스만 하고 이를 만들거나 수정하지 않는 경우에는 @ Page 지시문의 EnableSessionState 특성을 ReadOnly로 설정합니다.

    XML Web services 메서드에 대해 세션 상태를 비활성화할 수도 있습니다. 자세한 내용은 ASP.NET 및 XML Web services 클라이언트를 사용하여 만든 XML Web services를 참조하십시오.

    응용 프로그램의 세션 상태를 비활성화하려면 응용 프로그램에 대한 Web.config 파일의 SessionState 섹션에서 Mode 특성을 Off로 설정합니다.

    <sessionState mode="Off" />
    
  • 응용 프로그램의 필요에 맞는 세션 상태 공급자 선택   ASP.NET에서는 응용 프로그램의 세션 데이터를 저장할 수 있는 여러 가지 방법(in-process 세션 상태, Windows 서비스인 Out-of-process 세션 상태 및 SQL Server 데이터베이스의 Out-of-process 세션 상태)을 제공합니다. 사용자 지정 세션 상태 공급자를 만들어 선택한 데이터 저장소에 세션 데이터를 저장할 수도 있습니다. 각 방법마다 이점이 있지만 in-process 세션 상태는 빠른 솔루션이 아닙니다. 세션 상태에 적은 양의 volatile 데이터만을 저장하는 경우에는 in-process 공급자를 사용하는 것이 좋습니다. Out-of-process 세션 상태 옵션은 다중 프로세서 또는 여러 대의 컴퓨터에 응용 프로그램을 확장하거나 서버 또는 프로세스가 다시 시작될 때 세션 데이터를 유지하려는 경우에 유용합니다. 자세한 내용은 ASP.NET 세션 상태를 참조하십시오.

데이터 액세스

다음 지침에서는 응용 프로그램의 효율적인 데이터 액세스 방법을 제안합니다.

  • 데이터 액세스를 위해 SQL Server 및 저장 프로시저 사용   고성능의 확장 가능한 웹 응용 프로그램을 빌드하려면 .NET Framework에서 제공하는 모든 데이터 액세스 방법 중 SQL Server 기반 데이터 액세스를 사용하는 것이 좋습니다. 관리되는 SQL Server 공급자를 사용할 때 가능한 경우 SQL 명령 대신 컴파일된 저장 프로시저를 사용하면 추가적인 성능 향상을 얻을 수 있습니다. SQL Server 저장 프로시저를 사용하는 방법에 대한 자세한 내용은 매개 변수 구성(ADO.NET)을 참조하십시오.

  • 앞으로만 이동 가능한 빠른 데이터 커서에 대해 SqlDataReader 클래스 사용   SqlDataReader 클래스는 SQL Sever 데이터베이스에서 검색한 앞으로만 이동 가능한 데이터 스트림을 제공합니다. ASP.NET 응용 프로그램에서 읽기 전용 스트림을 사용할 수 있는 경우 SqlDataReader 클래스의 성능이 DataSet 클래스보다 우수합니다. SqlDataReader 클래스는 SQL Server의 네이티브 네트워크 데이터 전송 형식을 사용하여 데이터베이스 연결에서 직접 데이터를 읽습니다. 예를 들어, SqlDataSource 컨트롤에 바인딩하는 경우 DataSourceMode 속성을 DataReader로 설정하면 성능이 향상됩니다. 그러나 데이터 판독기를 사용하면 일부 기능이 손실됩니다. SqlDataReader 클래스는 데이터를 서버 컨트롤에 바인딩할 수도 있는 IEnumerable 인터페이스도 구현합니다. 자세한 내용은 SqlDataReader 클래스를 참조하십시오. ASP.NET의 데이터 액세스 방법에 대한 자세한 내용은 ASP.NET을 사용하여 데이터 액세스를 참조하십시오.

  • 가능한 경우 항상 데이터와 페이지 출력 캐시   ASP.NET에서는 모든 페이지 요청마다 페이지 출력이나 데이터를 동적으로 계산하지 않아도 되는 경우에 이를 캐싱하는 간단한 매커니즘을 제공합니다. 또한 특별히 많은 트래픽이 예상되는 사이트 영역에서 페이지와 데이터 요청이 캐싱되도록 디자인하면 해당 페이지의 성능을 최적화할 수 있습니다. 캐시를 적절하게 사용하면 .NET Framework의 다른 기능을 사용하는 것보다 사이트 성능을 훨씬 향상시킬 수 있습니다.

    ASP.NET 캐싱을 사용할 때 다음 사항에 주의해야 합니다. 첫째로, 너무 많은 항목을 캐시하지 마십시오. 각 항목을 캐시하는 데 메모리가 사용됩니다. 따라서 다시 계산하기가 쉽거나 사용 빈도가 낮은 항목은 캐시하지 않아야 합니다. 두 번째로, 캐시된 항목의 만료 기간을 짧게 지정하지 마십시오. 항목의 만료 기간이 너무 짧으면 불필요한 캐시 회전이 수행되고 정리 코드와 가비지 수집기의 작업량이 늘어날 수 있습니다. ASP.NET Applications 성능 개체에 연결된 Cache Total Turnover Rate 성능 카운터를 사용하여 만료되는 항목으로 인한 캐시 회전을 모니터링할 수 있습니다. 특히 항목이 만료되기도 전에 제거되는 경우처럼 회전율이 높으면 문제가 있는 것입니다. 이런 경우를 메모리 압력이라고도 합니다.

    페이지 출력과 데이터 요청을 캐시하는 방법에 대한 자세한 내용은 ASP.NET 캐싱 개요를 참조하십시오.

  • **SQL 캐시 종속성을 적절하게 사용   **ASP.NET에서는 사용 중인 SQL Server의 버전에 따라 테이블 기반 폴링과 쿼리 알림을 모두 지원합니다. 테이블 기반 폴링은 모든 버전의 SQL Server에서 지원됩니다. 테이블 기반 폴링에서는 테이블에 변경된 내용이 있으면 모든 수신기가 무효화됩니다. 이로 인해 응용 프로그램에서 불필요한 변동이 발생할 수 있습니다. 내용이 자주 변경되는 테이블의 경우 테이블 기반 폴링은 권장되지 않습니다. 예를 들어 테이블 기반 폴링은 내용이 자주 변경되지 않는 카탈로그 테이블의 경우에 권장되며, 업데이트가 잦은 주문 테이블의 경우에는 권장되지 않습니다. 쿼리 알림은 SQL Server 2005에서 지원됩니다. 쿼리 알림에서는 구체적인 쿼리를 지원하므로 테이블이 변경될 때 전송되는 알림의 수가 줄어듭니다. 이 방식은 테이블 기반 폴링보다 성능이 우수하지만 수천개의 쿼리로 확장하는 것은 불가능합니다.

    SQL 캐시 종속성에 대한 자세한 내용은 연습: SQL Server에 ASP.NET 출력 캐싱 사용 또는 ASP.NET에서 SqlCacheDependency 클래스를 사용한 캐싱을 참조하십시오.

  • **UI(사용자 인터페이스) 페이징 및 정렬 대신 데이터 소스 페이징 및 정렬 사용   **DetailsViewGridView와 같은 데이터 컨트롤의 UI 페이징 기능은 ICollection 인터페이스를 지원하는 모든 데이터 소스 개체에 사용할 수 있습니다. 각 페이징 작업에서 데이터 컨트롤은 데이터 소스에 전체 데이터 컬렉션을 쿼리하여 표시할 행 또는 열을 선택하고 나머지 데이터는 무시합니다. 데이터 소스에서 DataSourceView를 구현하고 CanPage 속성에서 true를 반환하는 경우 데이터 컨트롤에서는 UI 페이징 대신 데이터 소스 페이징을 사용합니다. 이 경우 데이터 컨트롤은 각 페이징 작업에서 필요한 행만 쿼리합니다. 따라서 데이터 소스 페이징은 UI 페이징보다 효율적입니다. ObjectDataSource 데이터 소스 컨트롤에서만 데이터 소스 페이징을 지원합니다. 다른 데이터 소스 컨트롤에서 데이터 소스 페이징을 사용하려면 이 데이터 소스 컨트롤에서 상속하여 동작을 수정해야 합니다.

  • **이벤트 유효성 검사의 보안상 이점과 성능 비용 간의 균형   **System.Web.UI.WebControlsSystem.Web.UI.HtmlControls 클래스에서 파생된 컨트롤에서는 이벤트가 발생한 지점이 컨트롤에서 렌더링한 사용자 인터페이스인지 여부를 확인할 수 있습니다. 이를 통해 컨트롤이 스푸핑된 이벤트 알림에 응답하는 것을 막을 수 있습니다. 예를 들어 DetailsView 컨트롤은 이 컨트롤에서 기본적으로 지원하지 않는 Delete 호출이 처리되어 데이터가 삭제되는 것을 막을 수 있습니다. 이 유효성 검사는 성능을 다소 저하시킵니다. EnableEventValidation 구성 요소 및 RegisterForEventValidation 메서드를 사용하여 이 동작을 제어할 수 있습니다. 유효성 검사로 인한 성능 비용은 페이지의 컨트롤 수에 좌우되며 몇 퍼센트의 성능 차이를 발생시킵니다.

    보안 정보:

    이벤트 유효성 검사는 해제하지 않는 것이 좋습니다. 이벤트 유효성 검사를 해제하기 전에, 응용 프로그램에 의도하지 않은 영향을 주는 방식으로 다시 게시를 구성할 수 없도록 해야 합니다.

  • **필요한 경우를 제외하고 뷰 상태 암호화를 사용하지 않음   **뷰 상태 암호화는 사용자가 숨겨진 뷰 상태 필드의 값을 읽을 수 없도록 합니다. 일반적인 시나리오는 DataKeyNames 속성에 ID 필드를 포함하는 GridView 컨트롤입니다. ID 필드는 레코드의 업데이트를 제어하는 데 필요합니다. ID는 사용자에게 노출되면 안 되므로 뷰 상태를 암호화하는 것이 좋습니다. 그러나 암호화는 초기화 과정에서 일정하게 성능을 저하시키며 암호화되는 뷰 상태의 크기에 따라 추가로 성능이 저하됩니다. 모든 페이지 로드에 대해 암호화가 설정되면 페이지가 로드될 때마다 동일한 성능 저하가 발생합니다.

  • **SqlDataSource 캐시, 정렬 및 필터링 사용   **SqlDataSource 컨트롤의 DataSourceMode 속성이 DataSet으로 설정되면 SqlDataSource에서 쿼리의 결과 집합을 캐시할 수 있습니다. 이 방식으로 데이터가 캐시되면 FilterExpressionSortParameterName 속성을 통해 구성된 컨트롤의 필터링 및 정렬 작업에 캐시된 데이터가 사용됩니다. 대부분의 경우에는 각 선택 작업에서 데이터베이스를 액세스하는 "WHERE" 및 "SORT BY" 절과 함께 SQL 쿼리를 사용하는 것보다 전체 데이터 집합을 캐시하고 FilterExpressionSortParameterName 속성을 사용하여 정렬 및 필터링을 수행하는 것이 응용 프로그램의 속도가 빠릅니다.

웹 응용 프로그램

다음 지침에서는 하나의 전체 작업으로서 웹 응용 프로그램의 효율성을 높이는 방법을 제안합니다.

  • 사전 컴파일 고려   웹 응용 프로그램은 ASP.NET 웹 페이지 같은 리소스를 처음으로 요청하면 일괄 컴파일됩니다. 응용 프로그램에 컴파일된 페이지가 전혀 없으면 디스크와 메모리를 더 효율적으로 사용하기 위해 디렉터리의 모든 페이지가 한꺼번에 일괄적으로 컴파일됩니다. ASP.NET 컴파일 도구(Aspnet_compiler.exe)를 사용하여 웹 응용 프로그램을 미리 컴파일할 수 있습니다. 현재 위치에서 곧바로 컴파일하는 경우 컴파일 도구는 ASP.NET 런타임을 호출하여 사용자가 웹 사이트에서 페이지를 요청할 때와 동일한 방식으로 사이트를 컴파일합니다. 웹 응용 프로그램을 미리 컴파일하여 UI 태그를 유지하거나, 페이지를 미리 컴파일하여 소스 코드가 변경되지 않도록 할 수 있습니다. 자세한 내용은 방법: ASP.NET 웹 사이트 미리 컴파일을 참조하십시오.

  • IIS 5.0에서 웹 응용 프로그램을 Out-of-process로 실행   기본적으로 IIS 5.0의 ASP.NET에서는 Out-of-process 작업자 프로세스를 통해 요청을 처리합니다. 이 기능은 처리 속도를 높이기 위해 조정되었습니다. Out-of-process 작업자 프로세스에서 ASP.NET을 실행하면 많은 장점이 있고 다양한 기능을 사용할 수 있으므로 프로덕션 사이트에 권장됩니다.

  • 프로세스를 정기적으로 재생   안정성 및 성능 측면을 모두 고려하여 프로세스를 정기적으로 재생해야 합니다. 오랜 기간 동안 리소스에 메모리 누수와 버그가 있으면 웹 서버 처리량에 영향을 줄 수 있으며 재생 프로세스는 메모리에서 이러한 유형의 문제를 제거합니다. 그러나 작업자 프로세스를 중지하고 페이지를 다시 로드한 후 리소스 및 데이터를 다시 얻는 비용이 재생으로 인한 이점보다 클 수 있으므로 자주 재생해야 하는 경우 이 점을 고려하여 균형을 맞춰야 합니다.

    IIS 6.0을 사용하는 Windows Server 2003에서 실행되는 ASP.NET 웹 응용 프로그램의 경우 ASP.NET에서 IIS 6.0 프로세스 모델 설정을 사용하므로 프로세스 모델 설정을 조정할 필요가 없습니다.

  • 필요한 경우 응용 프로그램의 작업자 프로세스별 스레드 수 조정   ASP.NET의 요청 아키텍처에서는 요청을 실행하는 스레드 수와 사용 가능한 리소스 간의 균형을 맞추려고 시도합니다. 이 아키텍처는 사용 가능한 CPU 성능만큼만 동시 실행 요청 수를 허용합니다. 이 기술을 가리켜 thread gating이라고 합니다. 그러나 thread-gating 알고리즘이 제대로 적용되지 않는 상황도 있습니다. ASP.NET Applications 성능 개체에 연결된 Pipeline Instance Count 성능 카운터를 사용하여 Windows 성능 모니터에서 thread gating을 모니터링할 수 있습니다.

    ASP.NET 웹 페이지에서 데이터베이스 액세스 또는 XML Web services 요청과 같은 외부 리소스를 호출하면 일반적으로 외부 리소스가 응답하여 CPU가 회수되고 다른 스레드를 처리할 수 있을 때까지 페이지 요청이 중지됩니다. 다른 요청이 처리를 기다리고 있을 때 스레드 풀에서 스레드가 회수되면 대기하고 있는 요청이 처리되기 시작합니다. 결과적으로 ASP.NET 작업자 프로세스나 응용 프로그램 풀에서 동시에 실행되는 요청 수와 대기 중인 스레드 수가 많으면 웹 서버의 처리를 방해하여 성능이 저하될 수 있습니다.

    이를 해결하려면 Machine.config 파일의 processModel 섹션에서 MaxWorkerThreadsMaxIOThreads 특성을 변경하여 프로세스의 스레드 수에 대한 제한을 직접 설정합니다.

    참고

    작업자 스레드는 ASP.NET 요청 처리를 위한 것이며, IO 스레드는 파일, 데이터베이스 또는 XML Web services로부터 데이터를 제공하는 데 사용됩니다.

    이 프로세스 모델 특성에 할당되는 값은 처리 중인 CPU당 각 스레드 형식의 최대 수입니다. 프로세서가 두 개인 컴퓨터일 경우 최대 수는 설정 값의 두 배입니다. 프로세서가 네 개인 컴퓨터에서는 설정 값의 4배입니다. 기본값은 프로세서가 한두 개인 컴퓨터에는 적합하지만 셋 이상의 프로세서가 장착된 컴퓨터에서 100 내지 200개의 스레드를 처리하는 경우 성능에 대한 장점보다 단점이 더 많을 수 있습니다. 처리 중인 스레드가 너무 많으면 추가 컨텍스트 스위치로 인해 서버가 느려지고, 운영 체제에서 요청 처리가 아니라 스레드를 유지하는데 CPU 사이클을 사용하게 됩니다. 적절한 스레드 개수는 응용 프로그램 성능 테스트를 통해 결정하는 것이 가장 좋습니다.

  • 외부 리소스를 많이 사용하는 응용 프로그램의 경우 다중 프로세서 컴퓨터에서 웹 가든 사용 고려   ASP.NET 프로세스 모델은 CPU당 하나씩, 프로세서 선호도가 CPU로 설정된 여러 프로세스에 작업을 분산하여 다중 프로세서 컴퓨터에서 확장을 가능하게 합니다. 이 기술을 웹 가든이라고 합니다. 응용 프로그램에서 느린 데이터베이스 서버를 사용하거나 외부 종속성을 가진 COM 개체를 호출하는 경우처럼 몇 개의 가능성만 고려한다면, 응용 프로그램에 웹 가든을 사용하는 것이 유익합니다. 그러나, 프로덕션 웹 사이트에서 이 기능의 사용을 결정하기 전에 웹 가든이 설정된 상태에서 응용 프로그램의 성능을 테스트해야 합니다.

  • 디버그 모드 비활성화   프로덕션 응용 프로그램을 배포하거나 성능 측정을 수행하기 전에는 항상 디버그 모드를 비활성화해야 합니다. 디버그 모드가 활성화되어 있으면 응용 프로그램의 성능이 저하될 수 있습니다. 디버그 모드 설정 구문에 대한 자세한 내용은 ASP.NET 구성 파일 편집을 참조하십시오.

  • 웹 서버 컴퓨터 및 특정 응용 프로그램에 대한 구성 파일을 요구에 맞게 조정   기본적으로 ASP.NET 구성은 가장 광범위한 기능 집합을 사용하고 가장 일반적인 시나리오를 수용하도록 설정되어 있습니다. 사용하는 기능에 따라 일부 기본 설정을 변경하여 응용 프로그램 성능을 향상시킬 수 있습니다. 다음 목록에는 고려해야 할 구성 설정이 포함되어 있습니다.

    • 필요한 응용 프로그램에 대해서만 인증 활성화   기본적으로 ASP.NET 응용 프로그램의 인증 모드는 Windows 또는 통합 NTLM입니다. 대부분의 경우 Machine.config 파일의 인증을 비활성화하고 필요한 응용 프로그램에 대해서만 Web.config 파일에서 인증을 활성화하는 것이 좋습니다.

    • 적절한 요청 및 응답 인코딩 설정으로 응용 프로그램 구성   ASP.NET 기본 인코딩은 UTF-8입니다. 응용 프로그램이 ASCII 문자만 사용하는 경우 약간의 성능 향상 효과를 얻을 수 있도록 ASCII에 맞게 응용 프로그램을 구성합니다.

    • 응용 프로그램에 대한 AutoEventWireup 비활성화 고려   Machine.config 파일에서 AutoEventWireup 특성을 false로 설정하면 페이지에서 이름 일치를 기반으로 페이지 이벤트를 메서드에 바인딩하지 않습니다(예: Page_Load). AutoEventWireup을 비활성화하면 자동으로 연결되는 대신 사용자가 이벤트를 연결하므로 다소의 성능 향상 효과를 얻을 수 있습니다.

      페이지 이벤트를 처리하는 데는 다음 두 전략 중 하나를 사용합니다. 첫 번째 전략은 기본 클래스의 메서드를 재정의하는 것입니다. 예를 들어 페이지 로드 이벤트에 대해 Page_Load 메서드를 사용하는 대신 Page 개체의 OnLoad 메서드를 재정의할 수 있습니다. 이 경우 모든 이벤트가 발생하도록 기본 메서드를 호출해야 합니다. 두 번째 전략은 Visual Basic의 Handles 키워드나 C#의 대리자 연결을 사용하여 이벤트에 바인딩하는 것입니다.

    • 요청 처리 파이프라인에서 사용하지 않는 모듈 제거   기본적으로 모든 기능은 서버 컴퓨터의 Machine.config 파일에 있는 HttpModules 노드에서 활성 상태로 남아 있습니다. 응용 프로그램에 사용되는 기능에 따라 요청 파이프라인에서 쓰지 않는 모듈을 제거하여 약간의 성능 개선 효과를 얻을 수 있습니다. 각 모듈 및 기능을 검토하고 사용자 요구에 맞게 사용자 정의합니다. 예를 들어, 응용 프로그램에서 세션 상태와 출력 캐싱을 사용하지 않는 경우 HttpModules 목록에서 제거하여 다른 처리 없이도 요청이 이러한 모듈을 호출할 필요가 없도록 할 수 있습니다.

코딩 작성 방법

다음 지침에서는 효율적인 코드 작성 방법을 제안합니다.

  • 코드에서 예외 사용 자제   예외는 성능을 상당히 저하시키므로 예외를 일반 프로그램 흐름을 제어하는 방법으로 사용하는 것을 자제해야 합니다. 코드에서 예외를 발생시키는 조건을 검색할 수 있는 경우 예외 자체를 catch하여 조건을 처리하는 대신 코드에서 조건을 검색합니다. 코드에서 검색하는 일반 시나리오에는 null을 확인하거나 숫자 값으로 구문 분석되는 String에 값을 할당하거나 수치 연산을 적용하기 전에 특정 값을 확인하는 것 등이 있습니다. 다음 예제에서는 예외를 유발할 수 있는 코드와 조건을 테스트하는 코드를 보여 줍니다. 두 코드의 결과는 같습니다.

    // This is not recommended.
    try {
       result = 100 / num;
    }
    catch (Exception e) {
      result = 0;
    }
    
    // This is preferred.
    if (num != 0)
       result = 100 / num;
    else
      result = 0;
    
    ' This is not recommended.
    Try
       result = 100 / num
    Catch (e As Exception)
      result = 0
    End Try
    
    ' This is preferred.
    If Not (num = 0)
       result = 100 / num
    Else
      result = 0
    End If
    
  • 호출을 많이 사용하는 COM 구성 요소를 관리 코드에서 다시 작성   .NET Framework에서는 기존의 COM 구성 요소와 상호 운용할 수 있는 손쉬운 방법을 제공합니다. 따라서 기존의 COM 구성 요소 속성을 유지하면서 .NET의 기능을 활용할 수 있는 이점이 있습니다. 그러나 이전 구성 요소를 유지하는 성능 비용이 구성 요소를 관리 코드로 마이그레이션하는 비용보다 많은 경우도 있습니다. 모든 상황이 다르므로, 구성 요소의 이식 여부를 결정하는 최선의 방법은 웹 사이트를 대상으로 성능 측정을 실행하는 것입니다. 자주 호출되는 COM 구성 요소를 관리 코드로 이식하는 것을 검토하는 것이 좋습니다.

    대부분의 경우, 특히 웹 응용 프로그램을 처음 마이그레이션하는 경우에는 레거시 구성 요소를 관리 코드로 마이그레이션할 수 없습니다. 이런 상황에서 성능에 가장 큰 장애가 되는 것은 관리되지 않는 환경에서 관리되는 환경으로 데이터를 마샬링하는 것입니다. 따라서 상호 운용을 할 때는 한쪽 또는 양쪽에서 가능한 한 많은 작업을 수행한 다음 작은 호출을 연달아 수행하는 것보다 하나의 호출을 실행하는 것이 좋습니다. 예를 들어, CLR(공용 언어 런타임)의 모든 문자열이 유니코드일 경우 관리 코드를 호출하려면 먼저 구성 요소의 모든 문자열을 유니코드로 변환해야 합니다.

    처리를 마치는 즉시 모든 COM 개체나 네이티브 리소스를 해제합니다. 그러면 다른 요청에서 이 리소스를 사용할 수 있으며 가비지 수집기가 나중에 해당 리소스를 해제할 때 발생할 수 있는 성능 문제를 최소화할 수 있습니다.

  • STA(단일 스레드 아파트) COM 구성 요소의 사용 방지   기본적으로 ASP.NET에서는 페이지 내에서 STA COM 구성 요소를 실행할 수 없습니다. 이 구성 요소를 실행하려면 .aspx 파일의 @ Page 지시문에 ASPCompat=true 특성을 포함시켜야 합니다. 그러면 페이지 실행에 사용되는 스레드 풀이 STA 스레드 풀로 전환되는 동시에 COM 개체가 HttpContext 및 기타 기본 제공 개체를 사용할 수 있게 됩니다. STA COM 구성 요소의 사용을 방지하면 MTA(다중 스레드 아파트)에서 STA 스레드로 마샬링하는 모든 호출이 방지되기 때문에 성능도 최적화됩니다.

    STA COM 구성 요소를 사용해야 하는 경우 실행 중에 잦은 호출을 피하고 각 호출을 통해 가능한 많은 양의 정보를 보내도록 해야 합니다. 또한 페이지를 작성할 때 STA COM 구성 요소가 만들어지지 않도록 합니다. 예를 들어, 다음 코드에서는 페이지를 작성할 때 페이지를 실행할 STA 스레드가 아닌 스레드를 바탕으로 만들어진 SampleSTAComponent에 의해 인스턴스화가 수행됩니다. 이 경우 페이지 구축을 위해 MTA와 STA 스레드 사이에서 마샬링을 수행해야 하므로 성능 손실이 생길 수 있습니다.

    <%@ Page Language="VB" ASPCompat="true" %>
    <script runat=server>
    Dim myComp as new SampleSTAComponent()
    Public Sub Page_Load()
        myComp.Name = "Sample"
    End Sub
    </script>
    <html>
    <%
        Response.Write(Server.HtmlEncode(myComp.SayHello))
    %>
    </html>
    

    다음 예제와 같이 STA 스레드를 통해 코드가 실행될 때까지 개체 만들기를 지연하는 메커니즘을 많이 사용합니다.

    <%@ Page Language="VB" ASPCompat="true" %>
    <script runat=server>
    Dim myComp
    Public Sub Page_Load()
        myComp = new SampleSTAComponent()
        myComp.Name = "Sample"
    End Sub
    </script>
    <html>
    <%
        Response.Write(Server.HtmlEncode(myComp.SayHello))
    %>
    </html>
    

    권장되는 방법은 필요할 때나 Page_Load 메서드에서만 COM 구성 요소와 외부 리소스를 구성하는 것입니다.

    구성에 사용되지 않은 스레드가 액세스할 수 있는 공유 리소스(예: 캐시 또는 세션 상태)에는 STA COM 구성 요소를 저장하지 마십시오. STA 스레드에서 STA COM 구성 요소에 호출을 하더라도 STA COM 구성 요소의 구축에 사용된 스레드만이 작성 스레드에 호출을 마샬링하는 호출을 처리할 수 있습니다. 이 마샬링에는 커다란 성능상 약점과 확장성 문제가 있을 수 있습니다. 이 경우 COM 구성 요소를 MTA COM 구성 요소로 만들거나 관리 코드에서 구성 요소를 다시 작성하십시오.

참고 항목

개념

ASP.NET의 성능 최적화

ASP.NET 응용 프로그램 성능 모니터

ASP.NET의 성능 카운터

ASP.NET 캐싱