13 steps you need to take to improve your web site performance

Consolidate your CSS

There is no reason to have more than 3 stylesheets in your application (with a few notable exceptions). In most cases, 1 will suffice. If you have a CSS for every page, you are doing it very very wrong. CSS should be reused across multiple pages. If the page is supposed to have the same theme as another, just different content, then why have a different CSS? Refactor your CSS so that it applies across your website. This not only makes it less to download, but makes it more manageable in the long term.

What many neophyte web designers do not realize, is that every single Javascript, CSS file, and image file represents a separate HTTP call. A web page has to make multiple trips to a website, and does so serially. That means the more files from the same site, the more calls it has to make, and each call adds latency to the web page. 

Consolidate your JavaScript

First, read the second paragraph above.
Second, look to see how you can reuse some Javascript functions. You might also delight in using a Javascript framework such as JQuery, or Dojo, which will make your Javascript writing more efficient, and allow you to reuse code that has already been written and perfected by someone else. 

Use a CDN to host your JavaScript frameworks

Remember my comment about pulling down multiple files in serial? Well, its only serial if its from the same web site. If from another website, it can do so in parallel. If you are using a Javascript framework, you can pull it from a content delivery network (CDN) such as Google's Hosted Library. This also means less HTTP traffic on your network, and therefor less work on your servers. Keep in mind however, that this may not work well if your target audience is behind a firewall. Some firewall might prohibit access to these sites. In such situations, you could host a CDN behind your firewall, and even host your own customized Javascript libraries (or CSS libraries).

Minify your static files

The YUI Compressor is a great utility to compress static text files such as CSS, and Javascript. It can be run on a command line. This removes redundant whitespace from these files, and optionally redundant semicolons. This can save as much as 70% in file size transfer. Now, your first objection might be "but I can't read minified Javascript when I'm debugging!". 

Well... duh! Don't minify it in your IDE, and certainly don't check in minified code to your SCM. Rather, make this part of your build automation, and minify it right before you package your WAR file. Add the following ANT lines into an ANT target (replace the variables accordingly). Then it gets minified on build, but yet is fully readable in your source editors and source code management systems.

<path id="yui.classpath">
<pathelement location="${yuicompressor.jar}"/>
<pathelement location="${yuicompressor-ant-task.jar}"/>

<yui-compressor warn="false" munge="true" jsSuffix=".js" cssSuffix=".css" preserveAllSemiColons="false" fromDir="${path.web}/common/js" toDir="${basedir}/js">
<include name="*.js"/>

If you use CDN delivered Javascript frameworks, make sure you at least use the minified version in production. 

Shrink your JSP's by moving styles into your style sheets

This is likely self descriptive, but the smaller your JSP, the less load on your application server. Move this into your CSS file. Same logic applies to Javascript functions in your JSP's. Move those functions into your JS files. Its easier to cache static content, than JSP's, thus taking further load off the application server. Also, only use an <img> tag if the image is part of the content. If its there for decoration, use a background-image attribute for a stylesheet. 

Combine smaller images into a single sprite

Some web sites that have lots of small images that represent controls, or navigational elements. Many are less than 10px in width or height. These can be combined into a single sheet, and referenced as sprites in a stylesheet using the following syntax:
#home {
    width: 46px;
    height: 44px;
    background: url(img_navsprites.gif) 0 0;

This can dramatically cut down on the number of HTTP calls and subsequently cut down on the total page load time.

Shrink your images

High resolution images are important, when they are part of the content. If they are merely decoration, such as in the case of stock images for a business web site, lose the resolution, and save some bandwidth. That image of people in business suits poised over a conference table does not need to be high definition 1920px wide. Such images can be as large as 2MB. When they load in a browser, they will typically buffer (i.e. slowly render from top to bottom). Worse, if they are as images, or in imported stylesheets, the whole site will wait until the entire image is loaded. This adds the most unneeded latency. In some cases, you might only need a portion of the image, but just dropped the entire stock image in the directory for convenience. In this situation, crop the image to only the dimensions you actually use. 

Replace images with CSS

I have a huge pet peeve with creating images of words because you want to use a font that is only available in Photoshop, or because you want some effect on the text. HTML5 and CSS3 allow you to use @font-face to load the font from a stylesheet on demand. The new standards also allow you to apply effects such as skew and text shadow Also, an image is not indexable, nor is it searchable by web crawlers, thus reducing your potential SEO. Remove the images, and put in simple text, decorated with CSS3 text effects

Always, always, ALWAYS use an HTTP Server - never your application server transport chain

No matter the Java application server you use, it will not be as efficient at HTTP transfer as a true HTTP server. Period. The WebSphere Application Server's HTTP transport chain is not an HTTP server. It serves up content as HTTP, but this is a raw I/O channel. Rather, it is easy to setup the IBM HTTP Server (or Apache Web Server) to front end the traffic. It offers the benefits of URL Rewriting, caching, and load balancing to back end clusters. Even with Tomcat, you should use the mod_jk module (i.e. the AJP connector) to front end with Apache. I even recommend using an HTTP server in front of web services servers. This allows the web server to proxy information into one of possibly many servers in a WebSphere cell (if you use WAS), without having to call a specific port for a specific JVM member. This means that you can move applications around to different application servers to best meet the resource demands, without affecting the web services consumer. 

Add a caching proxy for static content

When it comes to caching, the closer to the browser, the better. A caching proxy can cache images, style sheets, javascript files, and more for longer periods of time than a browser, and can intelligently cache it for multiple clients and applications. For example, if you have 50 applications in your environment and 20 of them use the same 10 images, and the same 5 Javascript libraries, then running traffic through an caching proxy means you save that much more traffic on your application server. 

Move validation logic to the browser

Form validation is now highly mature in Javascript frameworks, and while you shouldn't necessarily remove the validation from existing Java code, you are well served to add client side validation. This means less round-trips back to the server. 

Use WebSphere Dynacache or eXtreme Scale for dynamic caching

If you have data that cannot be cached, and must be calculated either on a session or application level, the WebSphere dynacache and eXtreme Scale are excellent tools to improve application response time. Both can be used to cache user session data, application context data, and more. Dynacache is included with all versions of WebSphere Application Server, but eXtreme Scale is bundled only with Network Deployment version. They do require some custom API calls to implement, and they do tie you to a specific application server. However, if you're going to need something this caliber, you're likely going to need the most scalable app server out there... which is WebSphere App Server. 

Scan and analyze your Java based web app

We could certainly go into great detail on application maintenance, but we can summarize all these steps in one category: static code analysis. If you are running Rational Application Developer (RAD), you have one of the most powerful static code analysis tools on the market. This best kept secret of RAD is extremely good at finding common anti-patterns. 
  • 541+ provided rules
  • Integrated results view with click-to-source navigation
  • Explanations, examples, and quick fixes
  • Supports customer rule creation based on rule templates
  • Extensive context sensitive help
  • Produces HTML/PDF reports with violations and violation metrics
  • Supports configuration of rule sets for use in different scopes and environments
  • Run interactively or invoke from command line
  • Integrate with automated builds
A single run with this tool can identify defects and performance bottlenecks before they occur. 

Labels: , ,