org.apache.click.extras.filter
Class PerformanceFilter

java.lang.Object
  extended by org.apache.click.extras.filter.PerformanceFilter
All Implemented Interfaces:
Filter

public class PerformanceFilter
extends Object
implements Filter

Provides a filter for improving the performance of web applications by setting Expires header on static resources and by compressing the HTTP response.

Please see Yahoo's Exceptional Performance best practices for speeding up your web site. This filter will enable you to apply the rules:

Apache Click can also help you with the following rules:

Click Static Resources

This filter will automatically add long expiry headers (5 years) to static Click resources such as CSS style sheets imports, JavaScript imports, and images. This will ensure these resources are cached in the users browser and will not have to be requested again. With Click, static resources are automatically deployed on startup to the web directory /click.

When the PerformanceFilter is active Click will add a version number to the static resource filenames and the long expiry header will be applied to these versioned files. When you upgrade the the next version of Click, this version number will increment, and the new static resources will be requested again and cached by the users browser.

When the PerformanceFilter is not active Click will not include a version number in the static resource filenames and no expiry header will be applied.

The filter will always GZIP compress non image, static Click resources, such as style sheets and JavaScript imports.

Configured Static Resources

You can also configure your application's static resources such as CSS, JS files and images to be processed by the filter.

This filter will automatically add long expiry headers to configured resources. The default expiry header is 1 year, but can be changed through the init-param "cacheable-max-age". This ensures the resources are cached in the users browser and will not have to be requested again.

The PerformanceFilter provides the ability to add versioning to application specific resources through the init-param "application-version". For example to set the "application-version" to 1.0 you can define the filter as follows:

 <filter>
  <filter-name>PerformanceFilter</filter-name>
  <filter-class>org.apache.click.extras.filter.PerformanceFilter</filter-class>
   <init-param>
     <param-name>application-version</param-name>
     <param-value>1.0</param-value>
  </init-param>
 </filter> 
Application versioning is supported by resource elements such as JsImport and CssImport. When the application version is set, ResourceElements will add the application version number to their filenames and PerformanceFilter will apply the long expiry header to these versioned files. When you increment the application version, the resource path will change and the static resources will be requested again and cached by the browser.

PerformanceFilter provides GZIP compression to compress HTML ServletResponse content. The content will only be compressed if it is bigger than a configurable threshold. The default threshold is 384 bytes but can be changed through the init-param "compression-threshold".

Click *.htm pages are automatically compressed by the filter.

It is also possible to disable GZIP compression by setting the init-param "compression-enabled" to false.

Page Template Import References

To import static control references in your page template you simply reference the $headElements and $jsElements. For example:
 <html>
 <head>
 $headElements
 </head>
 <body>
 $table
 </body>
 </html>
 $jsElements
HEAD elements should be included in the head section of your page, and JavaScript elements should be included at the bottom of your page to support progressive rendering in the browser.

Configuration

To configure your application to use the PerformanceFilter include the click-extras.jar in your application and add the following filter elements to your /WEB-INF/web.xml file:
 <filter>
  <filter-name>PerformanceFilter</filter-name>
  <filter-class>org.apache.click.extras.filter.PerformanceFilter</filter-class>
   <init-param>
     <param-name>cacheable-paths</param-name>
     <param-value>/assets/*, *.css</param-value>
  </init-param>
 </filter>

 <filter-mapping>
  <filter-name>PerformanceFilter</filter-name>
  <url-pattern>*.css</url-pattern>
 </filter-mapping>

 <filter-mapping>
  <filter-name>PerformanceFilter</filter-name>
  <url-pattern>*.js</url-pattern>
 </filter-mapping>

 <filter-mapping>
  <filter-name>PerformanceFilter</filter-name>
  <url-pattern>*.gif</url-pattern>
 </filter-mapping>

 <filter-mapping>
  <filter-name>PerformanceFilter</filter-name>
  <url-pattern>*.png</url-pattern>
 </filter-mapping>

 <filter-mapping>
  <filter-name>PerformanceFilter</filter-name>
  <servlet-name>ClickServlet</servlet-name>
 </filter-mapping>

 <servlet>
  <servlet-name>ClickServlet</servlet-name>
 .. 
The init-param "cacheable-paths", allows you to specify paths for resources such as JavaScript, CSS and images to be cached by the browser. (Caching here means setting the "Expires" and "Cache-Control" headers). The param-value accepts a comma separated list of directories and files to match against. To differentiate between directory and file values the following convention is used: This filter will automatically set the configured click.xml charset as the requests character encoding.

Frequently Asked Questions

How does compression work?

The response from non image (gif, jpg, png) content will be gzipped before writing to the browser. The browser will receive the gzipped content, unzip it, and display the content in its original form.

As the GZIP compression greatly reduces the size of HTML, CSS and JavaScript content these resources are downloaded faster and displayed quicker in the users browser.

GZIP compression is only applied if the browser supports it, and if the size of the content is greater than 384 bytes.

How does caching work?

For an explanation of how browsers and caching work, you can read the following article.

Only configured resources (see below) will have expiry headers added. The browser will not contact the server until the specified expiry date. When the resource expires, the browser will request a new copy from the server.

Does PerformanceFilter work in development, debug or trace modes?

PerformanceFilter is only applied in production and profile modes. In the development modes, this filter will simply pass through to ClickServlet without adding expiry headers or compressing content.

This ensures a smoother development experience. There is not need to worry about server and browser resources getting out of sync. In development mode, simply edit a javascript or style sheet and the browser will pick up the latest version.

Acknowledgments

This class is adapted from the Jakarta CompressionFilter from Tomcat.


Field Summary
protected  String applicationVersionIndicator
          The application resource version indicator.
protected  long cacheMaxAge
          The configured cache max age in seconds, default value is 1 year.
protected  boolean compressionEnabled
          Indicates if compression is enabled or not, default value is true.
protected  int compressionThreshold
          The threshold number to compress, default value is 384 bytes.
protected  ConfigService configService
          The application configuration service.
protected  boolean configured
          The filter has been configured flag.
protected static int DEFAULT_CACHE_MAX_AGE
          Default cache max-age in seconds (1 year): 31536000.
protected  List<String> excludeDirs
          The cacheable-path exclude directories.
protected  List<String> excludeFiles
          The cacheable-path exclude files.
protected  FilterConfig filterConfig
          The filter configuration object we are associated with.
protected static int FOREVER_CACHE_MAX_AGE
          Forever cache max-age in seconds (5 years).
protected  List<String> includeDirs
          The cacheable-path include directories.
protected  List<String> includeFiles
          The cacheable-path include files.
protected static int MIN_COMPRESSION_THRESHOLD
          Minimum compress threshold: 384 bytes.
 
Constructor Summary
PerformanceFilter()
           
 
Method Summary
 void destroy()
          Take this filter out of service.
 void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
          Perform the filter operation applying any necessary Expire headers and compressing the response content.
protected  String getApplicationResourceVersionIndicator(String path)
          Return the application version indicator for the specified path.
protected  ConfigService getConfigService()
          Return the application configuration service.
 FilterConfig getFilterConfig()
          Return filter config.
protected  String getResourceVersionIndicator(String path)
          Return the version indicator for the specified path.
 void init(FilterConfig filterConfig)
          Initialize the filter.
protected  boolean isExcludePath(String path)
          Return true if a path should be excluded from the performance filter.
protected  void loadConfiguration()
          Load the filters configuration and set the configured flat to true.
 void setFilterConfig(FilterConfig filterConfig)
          Set filter configuration.
protected  void setHeaderExpiresCache(HttpServletResponse response, long maxAgeSeconds)
          Set the response "Expires" and "Cache-Control" headers with the given maximum cache duration age in seconds.
protected  String stripResourceVersionIndicator(String path)
          Removes the version indicator from the specified path.
protected  boolean useConfiguredCacheHeader(String path)
          Return true if the response should be cached using the configured cache max-age.
protected  boolean useForeverCacheHeader(String path)
          Return true if a path is a static versioned resource and should be cached forever.
protected  boolean useGzipCompression(HttpServletRequest request, HttpServletResponse response, String path)
          Return true if the response should be GZIP compressed.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEFAULT_CACHE_MAX_AGE

protected static final int DEFAULT_CACHE_MAX_AGE
Default cache max-age in seconds (1 year): 31536000.

See Also:
Constant Field Values

FOREVER_CACHE_MAX_AGE

protected static final int FOREVER_CACHE_MAX_AGE
Forever cache max-age in seconds (5 years).

See Also:
Constant Field Values

MIN_COMPRESSION_THRESHOLD

protected static final int MIN_COMPRESSION_THRESHOLD
Minimum compress threshold: 384 bytes.

See Also:
Constant Field Values

cacheMaxAge

protected long cacheMaxAge
The configured cache max age in seconds, default value is 1 year.


compressionThreshold

protected int compressionThreshold
The threshold number to compress, default value is 384 bytes.


compressionEnabled

protected boolean compressionEnabled
Indicates if compression is enabled or not, default value is true.


configured

protected boolean configured
The filter has been configured flag.


configService

protected ConfigService configService
The application configuration service.


filterConfig

protected FilterConfig filterConfig
The filter configuration object we are associated with. If this value is null, this filter instance is not currently configured.


includeDirs

protected List<String> includeDirs
The cacheable-path include directories.


includeFiles

protected List<String> includeFiles
The cacheable-path include files.


excludeDirs

protected List<String> excludeDirs
The cacheable-path exclude directories.


excludeFiles

protected List<String> excludeFiles
The cacheable-path exclude files.


applicationVersionIndicator

protected String applicationVersionIndicator
The application resource version indicator.

Constructor Detail

PerformanceFilter

public PerformanceFilter()
Method Detail

init

public void init(FilterConfig filterConfig)
Initialize the filter.

Specified by:
init in interface Filter
Parameters:
filterConfig - The filter configuration object
See Also:
Filter.init(FilterConfig)

destroy

public void destroy()
Take this filter out of service.

Specified by:
destroy in interface Filter
See Also:
Filter.destroy()

doFilter

public void doFilter(ServletRequest servletRequest,
                     ServletResponse servletResponse,
                     FilterChain chain)
              throws IOException,
                     ServletException
Perform the filter operation applying any necessary Expire headers and compressing the response content.

Specified by:
doFilter in interface Filter
Parameters:
servletRequest - the servlet request
servletResponse - the servlet response
chain - the filter chain
Throws:
IOException - if an I/O error occurs
ServletException - if a servlet error occurs
See Also:
Filter.doFilter(ServletRequest, ServletResponse, FilterChain)

setFilterConfig

public void setFilterConfig(FilterConfig filterConfig)
Set filter configuration. This function is equivalent to init and is required by Weblogic 6.1.

Parameters:
filterConfig - the filter configuration object

getFilterConfig

public FilterConfig getFilterConfig()
Return filter config. This is required by Weblogic 6.1

Returns:
the filter configuration

getConfigService

protected ConfigService getConfigService()
Return the application configuration service.

Returns:
the application configuration service

loadConfiguration

protected void loadConfiguration()
Load the filters configuration and set the configured flat to true.


isExcludePath

protected boolean isExcludePath(String path)
Return true if a path should be excluded from the performance filter.

Parameters:
path - the request path to test
Returns:
true if the response should be excluded from the performance filter

getResourceVersionIndicator

protected String getResourceVersionIndicator(String path)
Return the version indicator for the specified path.

Parameters:
path - the resource path
Returns:
a version indicator for web resources

getApplicationResourceVersionIndicator

protected String getApplicationResourceVersionIndicator(String path)
Return the application version indicator for the specified path.

Parameters:
path - the resource path
Returns:
an application version indicator for web resources

stripResourceVersionIndicator

protected String stripResourceVersionIndicator(String path)
Removes the version indicator from the specified path.

For example, given the path '/example/control_1.4.js', where '_1.4' is the version indicator, this method will return '/example/control.js'.

Parameters:
path - the resource path
Returns:
path without the version indicator
See Also:
getResourceVersionIndicator(String), getApplicationResourceVersionIndicator(java.lang.String)

setHeaderExpiresCache

protected void setHeaderExpiresCache(HttpServletResponse response,
                                     long maxAgeSeconds)
Set the response "Expires" and "Cache-Control" headers with the given maximum cache duration age in seconds.

Parameters:
response - the response to set the headers in
maxAgeSeconds - the maximum cache duration in seconds

useForeverCacheHeader

protected boolean useForeverCacheHeader(String path)
Return true if a path is a static versioned resource and should be cached forever.

Parameters:
path - the request path to test
Returns:
true if the response should be cached forever
See Also:
getResourceVersionIndicator(java.lang.String), getApplicationResourceVersionIndicator(java.lang.String)

useConfiguredCacheHeader

protected boolean useConfiguredCacheHeader(String path)
Return true if the response should be cached using the configured cache max-age.

Parameters:
path - the request path to test
Returns:
true if the response should be cached with the configured max-age

useGzipCompression

protected boolean useGzipCompression(HttpServletRequest request,
                                     HttpServletResponse response,
                                     String path)
Return true if the response should be GZIP compressed.

Parameters:
request - the request to test
response - the response to test
path - the request path to test
Returns:
true if the response should be GZIP compressed