Programming/.NET

1. 출력캐시(Output Cache)

 

출력캐시는 페이지의 컨텐츠 내용을 서버의 메모리나 디스크에 저장하고 사용자가 해당 페이지를 다시 요청하는 저장한 내용을 반환해주는 방법입니다. 동적으로 생성된 페이지의 경우에도 최종 렌더링이후의 내용을 저장하고 사용자에게 반환합니다.

 

특정 페이지에 출력캐시를 지정하려면 다음과 같이 OutputCache선언문을 사용합니다.

 

<%@ OutputCache Duration="60" VaryByParam="None" %>

 

Duration은 캐시가 저장될 시간을 설정합니다. 해당 시간이 지나면 저장된 컨텐츠는 만료됩니다. 시간단위는 '초'입니다.

 

 1. VaryByParam

 

페이지가 호출될때 다음과 같은 형식으로 페이지가 호출된다고 가정해 보겠습니다.

 

http://www.testsite.com/default.aspx?userid=cliel

 

default.aspx페이지는 GET로 받아들인 userid값에 따라 다른 내용을 출력하는 페이지입니다. 이러한 형태의 페이지를 캐시하고자 하는 경우에는 userid값이 따라 각각 개별적으로 페이지를 캐시해야할 필요가 있을 것입니다. 이럴 때 VaryByParam을 다음과 같이 설정해야 합니다.

 

<%@ OutputCache Duration="60" VaryByParam="userid" %>

 

만약 GET으로 받아들이는 매개변수가 2개 이상인 경우에는 ; 문자로 구분해 지정해 주면 됩니다.

 

<%@ OutputCache Duration="60" VaryByParam="userid;username" %>

 

만일 매개변수가 너무 많거나 매개변수의 구분없이 모든 값에 대응하여 캐시해야 하는 경우에는 * 문자를 사용합니다.

 

<%@ OutputCache Duration="60" VaryByParam="*" %>

 

 2. VaryByHeader

 

특정 헤더값에 따라 페이지를 캐시해야 하는 경우 VaryByHeader 특성을 사용합니다. 예를 들어 헤더의 User-Agent값을 구분하여 캐시하고자 한다면 다음과 같이 지정합니다.

 

<%@ OutputCache Duration="60" VaryByParam="None" VaryByHeader="User-agent" %>

 

 3. VaryByControl

 

이 특성을 사용하면 특정 컨트롤의 데이터만을 캐시할 수도 있습니다.

 

예를 들어 수강신청시스템에서 수강하고자 하는 과목을 선택하는 ComboBox컨트롤이 존재할때 이 컨트롤은 페이지가 호출될때마다 현재의 모든 과목을 DB에서 불러와 표시할 수 있을 것입니다. 만약 과목이 자주 변하지 않는다는 전제가 있는 경우 ComboBox에서 표시되는 최종 결과를 캐시하도록 하면 사용자에게 좀 더 빠른 출력을 제공할 수 있을 것입니다.

 

<%@ OutputCache Duration="60" VaryByParam="None" VaryByControl="cmb_Subject" %>

 

VaryByControl 특성에는 Control의 ID를 지정합니다.

 

 4. VaryByCustom

 

임의의 값에 따라 캐시처리를 해야 하는 경우 VaryByCustom 특성을 사용합니다.

 

<%@ OutputCache Duration="60" VaryByParam="None" VaryByCustom="cache" %>

 

이 값은 페이지의 GetVaryByCustomString 메소드를 오버로드하여 custom으로 넘어오는 매개변수를 읽는 방법으로 확인해야 합니다.

 

public override string GetVaryByCustomString(HttpContext context, string custom)
{
    if (custom == "cache") {

    }

    return base.GetVaryByCustomString(context, custom);
}

 

이 메소드는 Global.asax 페이지에 정의되어야 합니다.

 

2. 부분페이지캐시(Page Partial Cache)

 

부분 페이지 캐시는 정확히 말해 여러 페이지에서 공통적으로 사용하는 '사용자 정의 컨트롤(ascx)'을 캐시합니다. 만약 특정 ascx에서 OutputCache 선언이 존재한다면 이 컨트롤을 사용하는 각 페이지에서 개별적으로 컨트롤이 캐시되는데 Shared속성을 true로 추가하면 단 한번만 캐시되어 ascx를 사용하는 모든 페이지에서 공통적으로 캐시된 ascx를 사용하게 됩니다.

 

<%@ OutputCache Duration="120" VaryByParam="None" Shared="true" %>

 

ascx에 OutputCache가 걸려 있고 이를 사용하는 페이지가 출력된다면 실제 ascx컨트롤이 해당 페이지에 들어가지 않고 대신 PartialCachingControl이 생성되어 기존 ascx컨트롤을 대체하여 최종 HTML이 렌더링됩니다. 결론적으로 aspx에는 캐시된 PartialCachingControl이 존재할뿐 실제 ascx컨트롤은 존재하지 않는 것입니다.

 

이 상태에서 ascx에 접근하여 무엇인가를 처리하려고 한다면 경우에 따라 오류가 발생할 가능성이 많습니다. 이를 예외적으로 처리하기 위해 aspx의 cs코드에서는 다음과 같이 PossiblyCachedUserControl이 존재하는지를 확인하고 처리해야 합니다.

 

if (custom_control == null) {
    //없음
}
else {
    //있음
}

 

3. 캐시 치환

 

페이지 전체를 캐시하더라도 특정 부분은 항상 동적인 데이터를 출력해야 하는 경우가 있습니다. 이런 경우에는 우선 캐시된 페이지를 출력하고 나서 특정 메소드를 호출하여 원하는 데이터를 끌어오는 방법을 사용할 수 있습니다. 이걸 '캐시 치환'이라고 합니다.

 

<form id="form1" runat="server">
<div>
    <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
    <asp:Substitution ID="Substitution1" runat="server" MethodName="GetTime" />
</div>
</form>

 

캐시 치환에는 Substitution 컨트롤이 사용됩니다. 이 컨트롤에는 MethodName속성으로 GetTime라는 정적메소드의 이름이 지정되었습니다.

 

protected void Page_Load(object sender, EventArgs e)
{
    Label1.Text = "cliel";
}

public static string GetTime(HttpContext context)
{
    return DateTime.Now.ToString();
}

 

호출할 메소드는 정적메소드여야 하며 HttpContext개체를 매개변수로 전달해야 합니다. 이와 같은 방법으로 메소드에 원하는 데이터를 가져오도록 하면 Substitution컨트롤부분에 동적데이터를 표시할 수 있습니다.

0 0