Measuring Web Mapping Application Performance using YSlow – part 2

Sorry for the long delay in writing this post. Lots of you have emailed me asking for the concluding part of the performance analysis and here it is. This is a continuation from the last post so its highly recommended you read the earlier post first (Click here for part1)

Here is the listing of YSlow 13 performance rules along with the ratings given to the default web mapping application template.

1. Make Fewer HTTP requests (F)
2. Use a CDN (F)
3. Add an Expires header (F)
4. Gzip components (F)
5. Put CSS at the top (B)
6. Move scripts to the bottom (C)
7. Avoid CSS expressions (A)
8. Make JS and CSS external (-)
9. Reduce DNS lookups (A)
10. Minify JS (A)
11. Avoid redirects (A)
12. Remove duplicate scripts (A)
13. Configure ETags (A)

Now lets analyze a few rules and its ratings to see where we as web developers or front end engineers can contribute to improve the performance of the web mapping application.

1. Make Fewer HTTP requests (F)

The tools measures this with respect to how many http requests the application makes while loading in the browser. From a web mapping application perspective this cannot be controlled easily since the web mapping application downloads around 16 Javascript files and 2 css files which the YSlow does not like. Its hard to modify this since the Javascript files are injected to the html at initialization by the XSL files and you will have to modify a lot of XSL to reduce this. Not recommended.

2. Use a CDN (F)

CDN stands for Content Delivery/Distribution Network. Its not practical/economical for small scale web applications with less than 10,000 hits a day to be served from CDN.

3. Add an Expires header (F)

Here is where it gets interesting. This rule is suggesting that any web resource transported to the browser  for example images, javascript, css, html files can be and shoud be cached by the browser.

Oh well, what can we as Front End Engineers or Web Developers do to improve the grade and get a better performance and user experience. In the web application we can add custom headers such as “Expires” and “Cache-Control” to these resources so that the browser will download it once and until the user clears the browser cache the files are reused. A big performance gain and potentially saves lots of bandwidth.

Here is a snippet from web.xml where I have declared a filter to do the job.

<filter>
<filter-name>ResponseHeaderFilter</filter-name>
<filter-class>
com.esri.sample.ResponseHeaderFilter
</filter-class>
<init-param>
<param-name>Cache-Control</param-name>
<param-value>max-age=3600</param-value>
</init-param>
<init-param>
<param-name>Expires</param-name>
<param-value>Thu, 14 Aug 2008 12:00:00 GMT</param-value>
</init-param>
</filter>

Here is the actual implementation – “ReponseHeaderFilter.java”

package sample;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

public class ResponseHeaderFilter implements Filter {
FilterConfig fc;

public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;

// set the provided HTTP response parameters
for (Enumeration e=fc.getInitParameterNames();e.hasMoreElements()) {
String headerName = (String)e.nextElement();
response.addHeader(headerName, fc.getInitParameter(headerName));
}

// pass the request/response on
chain.doFilter(req, response);
}

public void init(FilterConfig filterConfig) {
this.fc = filterConfig;
}

public void destroy() {
this.fc = null;
}
}

Here is the filter mapping in web.xml to identify the type of resources to add the headers

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

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

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

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

<filter-mapping>
<filter-name>ResponseHeaderFilter</filter-name>
<url-pattern>*.jpg</url-pattern>
</filter-mapping>

<filter-mapping>
<filter-name>ResponseHeaderFilter</filter-name>
<url-pattern>/tile/*</url-pattern>
</filter-mapping>

<filter-mapping>
<filter-name>ResponseHeaderFilter</filter-name>
<url-pattern>/mimedata/*</url-pattern>
</filter-mapping>

4. Gzip components (F)

The time to send response from your application/web server across the network back to the browser can be significantly reduced by compressing certain types of responses. If you want to learn more on this for all the goodness and benefits of Compression, click here. You will have to rely on the web server to provide this functionality for you and here is an example of modifying tomcat’s configuration file to compress different types of responses based on their mime-type.

Note: In this case we are configuring the server.xml file of Tomcat (6.0.14 version) to compress using the GZip compression type for the following mime-types: text/html,text/xml,text/javascript,text/image,text/css

We are not compressing any image formats here since compression on image or pdf formats is not recommended since it is already in a compressed format.

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"
compression="on"
compressionMinSize="512"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="text/html,text/xml,text/javascript,text/image,text/css"/>

The server.xml can be found under the “{tomcat installationfolder}/conf” folder and by default will not have the compression turned on. Open the server.xml file in any text editor and find the and add the compression attributes as shown above. In my example, I have asked Tomcat to compress any html, text, xml, javascript or css files which is over 512 bytes.

This change will significantly boost the performance of your application both at start up follwed by every AJAX call made to the server since the Java ADF uses XML to send responses back to the calling web application. Also this change changes the YSlow grade of F to A for this category.

6. Move scripts to the bottom (C)

This is pretty simple change. YSlow checks to see if there are any external Javascripts files in the page and if yes then is it at the end of the body rather than at the head. The web mapping application has a few script tags in the mapviewer.jsp at the head. You can move them all the way to the end of the page before the html tag ends. This will imporive the loading of the page and also please the YSlow rating.

10. Minify JS (A)

Wanted to make a small comment here. In version 0.9.x YSlow gives grade A for this rule when the Javascript libraries of the Web Mapping application is not minified. This might be a bug with the YSlow plugin, anyways we should aim to minify the JS libraries as it will imporove the transport speed of the files and remember there are atleast 16 Javascript files transported in the web mapping application, so we should revisit this topic seperately. Its worth a post of its own.

So here it is folks, after making all these changes here is final screenshot of the new Yslow rating :

We can see a significant improvement in rating (from F to B), performance and responsiveness of the application by just following a few simple rules. If you try this out, please share the performance metrics so that others can comment on it.

Advertisements

One Response to “Measuring Web Mapping Application Performance using YSlow – part 2”

  1. Lincoln Baxter III Says:

    Great tutorial — thanks :)


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: