APGen Documentation Previous Topic: Two-Phase Content Generation Next Topic: Dynamic Pages Parent Topic: Web Site Optimization Techniques    Web Site Optimization Techniques
Page Fragment Caching
See Also:

Page fragment caching offers high-performance pages, while keeping some page content dynamic.  Additionally, page fragment caching offers more efficient CPU and memory utilization than two-phase content generation for pages with multiple output combinations.

Definition

Page fragment caching is similar to two-phase content generation, in that APGen is used to generate part of the page before it is displayed, and ASP is used to generate dynamic content when the page is requested.

The page fragment caching technique involves generating multiple static page fragments in the first phase.  An APG script is written that generates the page fragment(s).  For example, in the Adventure Works Example, an APG script named catalog_type_frag.apg generates one page fragment for each "catalog type" in the database.  The fragments are catalog_type_Backpack.htm, catalog_type_Boot.htm, ...

In the second phase, the ASPCache component is used to cache and write out the contents of a page fragment.  In our example, the fragments are "dynamically included" in catalog_type.asp at run time.  The ASPCache object caches file handles or contents of frequently used page fragments in memory (for more information see the ASPCache documentation).  In addition, ASPCache writes the contents of the page fragment to the Response object.  ASPCache is highly optimized for storing and writing static page fragments.

Advantages

Page fragment caching provides superior performance to unoptimized pages and to data caching.  The performance benefits of using this technique are significant, typically resulting in throughput gains of 20 times (compared to unoptimized pages) and reduced database load.

The ASPCache object is highly optimized for data caching and for page fragment caching.  For data caching, our tests show that ASPCache is 20+ times faster than the ASP Application object and 300+ times faster than the Commerce.Dictionary from Site Server Commerce Edition 3.0:

ASPCache Collection Performance
Times are in milliseconds
  ASPCache ASP
Application Object
Site Server
Commerce.Dictionary
Add/Update 50000x 811 16463 245729
Read 60000x 461 11877 211770
Remove 2000x 110 881 N/A
Tests were run on a 600MHz single-proc computer. The overhead of script execution has been subtracted. All operations used random keys from a pool of 20,000.
"Add/Update 50000x" means 50,000 add or update operations took this long. "Read 60000x" means 60,000 read operations took this long. etc.

Page fragment caching is more memory and CPU efficient than any other design (including two-phase content generation) for pages with multiple output combinations.  With page fragment caching, a single ASP page is compiled and cached by the ASP engine (several instances of the compiled code may be cached, but it is only compiled once).  With two-phase content generation, one ASP page is generated for each output combination, and these must each be individually compiled and cached by asp.dll.  Each cached ASP instance occupies 3 to 5 MB of RAM.  Thus page fragment caching is usually the best choice for dynamic pages with multiple output combinations.

It is important to note that page fragment caching and two-phase content generation can be used together on a single page.

Disadvantages

Though page fragment caching is much faster than data caching or no optimization, two-phase content generation performs slightly better, and static pages perform much better.

Page fragment caching is more difficult to implement than two-phase content generation: Page fragment caching requires one ASP file as the host page, and one APG script per page fragment.  Two-phase content generation does not require breaking out the fragments or maintaining two or more files as part of a whole page.

How to Implement Page Fragment Caching

To implement page fragment caching:

  1. Write APG script(s) that generate static page fragments.  In the Adventure Works Equipment example, catalog_type_frag.apg and navbar2_frag.apg generate fragments that are written to the awe_apg/producttypes/ directory.
  2. Write code to execute the page fragment script(s).  The page fragment script(s) should be executed once for each output combination.  In the Adventure Works Equipment example, build.asp loops through all the product types, executing the page fragment scripts once for each product type.
  3. Instantiate an ASPCache object in global.asa.  It must be declared with Application scope so it can be accessed from every page:

    REM  *** global.asa ***

    <OBJECT RUNAT=Server SCOPE=Application ID=Cache PROGID=ASPCache></OBJECT>

  4. Include the page fragment(s) in the host page.  In the ASP page that hosts the page fragment, use the Cache.WriteFile() method to write the page fragment to the ASP Response object.  In the Adventure Works Equipment example, catalog_type.asp uses this code to write the navbar fragment and catalog_type fragment for the product being viewed:

    <%
    Option Explicit

    Dim sProductType
    sProductType = Request.QueryString("ProductType")
    If sProductType = "" Then
         Response.Redirect("default.asp")
    End If
    %>

    <HTML>
    <HEAD>
    <TITLE>Adventure Works Catalog</TITLE>
    </HEAD>

    . . .

    <!--Begin Navigational Buttons-->

    <TR>
    <TD ROWSPAN=5 ALIGN=LEFT VALIGN=TOP>
    <%     ' Insert the navbar fragment for this product
    If Not Cache.WriteFile( "producttypes\navbar2_" & sProductType & ".htm", _
                                   True, True, 0, Response ) Then
         Response.Redirect("default.asp")
    End If
    %>
    <BR>

    <%If Session("ItemCount") > 0 Then%>
         <A HREF="./check_out.asp">
         <IMG SRC="../awe_asp/images/checkout.gif" WIDTH="85" HEIGHT="45" ALT="Check Out" BORDER=O></A>
    <%End If%>
    </TD>


    <%     ' Insert the body fragment for this product
    If Not Cache.WriteFile( "producttypes\catalog_type_" & sProductType & ".htm", _
                                   True, True, 0, Response ) Then
         Response.Redirect("default.asp")
    End If
    %>

    </TABLE>
    </BODY>
    </HTML>