Improving Performance of Dynamic Web Pages

How the ESI Sample Application Works

Contents

This article describes a sample application that uses Oracle9i Application Server, Oracle9iAS Web Cache, and Edge Side Includes (ESI) to deliver Web pages of dynamic, personalized content. The main part of the sample is a JSP-based portal page. It uses Edge Side Includes for Java (JESI) to identify content fragements (some cached, some not) and define a template so a complete Web page can be assembled on demand at the edge of the Internet. This strategy reduces the load on back-end servers and enables applications to make better use of the cache, accelerating overall performance. The sample also renders the same portal page without using JESI or a cache so you can observe the performance difference first-hand.

About ESI

With ESI, you can divide Web pages into fragments.The ESI specification defines a way to improve performance by reducing the back-end processing load when delivering dynamic content and applications via the Web. The current version defines four areas: markup language, architecture, invalidation protocol, and a Java ESI tag library. A key concept is the notion of page fragments (text, images, forms, and anything else that can be contained in an HTML document). The figure at right shows a Web page built from static fragements (examples: titles and buttons) and dynamic, personalized fragments (examples: stock quotes, news headlines, and weather data). An ESI template defines a container for fragments and specifies how to build a Web page from those fragments.

The ESI specification defines an XML-based mark-up language for defining templates and identifing page fragments. WIth ESI, applications can deliver Web pages to users faster because only truly dynamic fragments need to be generated on demand (examples: real-time data, or transactions such as adding items to a shopping cart or paying a bill). Static fragments and semi-dynamic fragments (example: temperature data gathered every 30 minutes) can be served from a cache.

Without ESI, back-end infrastructure carries a heavy processing burden.In contrast, consider how things typically happen today, without ESI. Clients issue requests, and Web servers, application servers, and databases access expensive hardware to generate the content, assemble the pages, and then return them to the clients. The back-end infrastructure has to handle every request, and as requests increase, performance can degrade. Static pages can be prebuilt and cached to ease some of the burden, but any page with truly dynamic content must be completely rebuilt each time it is requested.

ESI provides features that improve the performance of dynamic Web pages. You can break a page into fragments, and each fragment can have a cacheability profile: you can specify whether a fragment is cached, and if it is cached, when it should expire. ESI tags also support conditional logic, so pages can be assembled based on information in HTTP request headers or browser cookies. The ESI architecture provides for intermediaries (also called reverse proxies) that can process ESI tags and act on behalf of the Web server. Oracle9iAS Web Cache (part of Oracle9i Application Server) includes an ESI processor. For even faster performance, ESI lets you distribute page-building chores throughout a content delivery network (CDN) of low-cost servers deployed across the Internet or a private intranet.

For even faster performance, ESI lets you distribute page-building chores throughout a content delivery network (CDN) of low-cost servers.Here's the flow of events:

  1. Client browser requests dynamic content from Web site.
  2. Oracle9iAS Web Cache includes an ESI processor that returns dynamically-generated HTML with embedded HREF links (for static elements) that reference the CDN service's domain.
  3. Client browser requests referenced static objects from the CDN.
  4. The CDN's distributed DNS mechanism chooses the optimal cache server to respond to requests for static content.

     

ESI and JESI

Conceptually similar to SSI (Server-Side Includes), ESI is an in-markup scripting language that is interpreted before the page is served to the client. The core ESI language is based on XML and defines tags that define templates and identify page fragments, typically in HTML documents.

The following table summarizes the ESI tags.

Tag Description
<esi:include>
Include a cacheable fragment.
<esi:choose>
Conditional execution based on, for example, cookie value or user agent.
<esi:try>
Specify alternative processing when a request fails.
<esi:vars>
Permit variable substitution (for environment variables).
<esi:remove>
Specify alternative content to be stripped by ESI but displayed by the browser if ESI processing is not done.
<!--esi ... -->
Specify content to be processed by ESI but hidden from the browser.
<esi:inline>
Include a cacheable fragment whose body is included in the template.

Edge Side Includes for Java (JESI) extends the Java programming language and makes it easy to write JSPs (JavaServer Pages) using ESI. The JESI tag library, provided with OracleJSP, can simplify common tasks such as:

  • Specifying meta-data information, such as expiry time of page fragments, conveniently within the JESI tags.
  • Sending invalidation messages to purge URLs and expire cached items.
  • Personalizing dynamic pages using cookie information.

JESI tags translate into appropriate calls, such as generating a HTTP request for invalidation, translating into the appropriate ESI tag in the generated page, setting the appropriate HTTP response header, etc. For example, the following JSP code contains JESI tags that include the results returned by another JSP for a specified login name:

<% if (l_page == 'S' ) { 
l_url = "CachedStocks.jsp?loginname="+l_pageLoginname; %>
<jesi:include page="<%=l_url%>" />
<% } %>

The following table summarizes the JESI tags.

Tag Description
<jesi:template> Declares a template and its attributes.
<jesi:include> Identifies a fragment in a template. This JSP tag generates <esi:include> tag.
<jesi:fragment> Identifies a fragment in a JSP page.
<jesi:param> Used within a <jesi:include> tag to specify additional parameters.
<jesi:codeblock> Declares a code block to execute (examples: authenticate a user or connect to the database) before processing fragments.
<jesi:control>

Declares attributes (example: expiration) of templates and fragments.

Design Notes

This sample application is a portal that displays:

  • Stocks
  • Weather
  • Headlines
  • Horoscope
  • To Do task items for the day

Some of the portal content is generated by providers like quotes.nasdaq.com, weather.yahoo.com, and astrocenter.com. Other content (example: tasks in the user's To Do list) comes from the database. The end-user can customise portal categories, for example, by choosing which stocks to track. This application also allows the user to change the color scheme, headings, refresh rate, and layout. The application stores each user's profile in the database and uses it to select content for the page.

The sample app renders the same portal content in two different frames.To demonstrate how caching fragments can improve performance, this sample application renders the same portal content in two different frames: the upper frame uses the cache, the lower frame does not. When you load this page the first time, the cache is empty, so the time required to render each frame is about the same, depending on network traffic, bandwidth, and other factor external to the application itself. On subsequent loads, though, the upper frame can use cached data to render the portal much faster, while load times for the lower frame don't change much. (Note: If your browser caches pages and page elements locally, you may see an improvement in load times for the lower frame, as well, but the upper frame will still load faster.) Each time it loads the portlets, the application displays a graph so you can compare performance with and without cached fragments.

The main portal page is built from a template consisting of category fragments and sub-fragments. For example, a stock quote category fragment includes sub-fragments for ticker symbol, price, and change. Category fragments are cached for each user, because their content changes for every user. The sub-fragments carry the same information for every user and they are cached at global level and are available to all users. The expiration time of a category fragment is customizable for every user. Expiration of sub-fragments can be set at the application level.

When a user customizes a category of information, only that particular category is invalidated in the cache. So, the next request for the portal page has to fetch only the invalidated information—the rest can be fetched from the cache. You can observe this behavior by customizing the layout of the page or by customizing any category information. The frame without the cache takes longer to fetch the data because it must rebuild the page from scratch, a process that includes aggregrating the content from all content providers.

The cached version offers additional benefits via globally cached fragments, enabling the demo to increase performance as more people use the application, because more fragments are cached. Example: As more people request more stock quotes, more stock quotes are stored in the cache, increasing the probability that, when a user requests a quote, the corresponding fragment will be in the cache.

The rest of this article describes the cached version in more detail.

Implementation Notes

The application is implemented using JSPs to declare HTML page templates and identify content fragments. The JSPs invoke a JavaBean (implemented in MyPortalBean.java) to perform tasks such as retrieving data from providers (e.g., stock quotes from nasdaq.com) and querying the database (e.g., to fetch a user's to-do items).

Declaring Content Fragments

Each category of information displayed in the portal is declared as a fragment in a JSP. The various fragments are identified using the JESI tags and are assembled at run time. The application stores each person's profile information including the customizable options like color, title of the page, and refresh rate for each fragment and layout style of the content. This information is passed to edge server as cookie/session information, which is used by the JESI tags and then assembled on the fly at the edge server, not at the application Web server.

The following code comes from CachedStocks.jsp.

    <TR>
<%
// stock quote url for each of the stock quotes
String l_symbol[] = (String []) l_symbols.elementAt(i);
String l_url = "CachedStock
E-mail this page
Printer View Printer View
Oracle Is The Information Company About Oracle | Oracle RSS Feeds | Careers | Contact Us | Site Maps | Legal Notices | Terms of Use | Privacy