Yahoo published a list of best practices for improving web application performance.
Click Framework provides a PerformanceFilter which caters for some of these rules. However not all rules can be easily automated.
This entry will outline ways to apply rules which are not covered by the PerformanceFilter namely, #1 - Minimize HTTP Requests (by combining files) and #10 - Minify Javascript and CSS.
Rule #1 also mentions CSS Sprites, a method for combining multiple images into a single master image. CSS Sprites is not covered here.
It is worth pointing out that its not necessary to blindly optimize every page in an application. Instead concentrate on popular pages, for example a web site's Home Page would be a good candidate.
There are a couple of tools that are useful in applying Rule #1 and #10:
- YUICompressor - minifies and compresses JavaScript and CSS files so less bytes have to be transferred across the wire.
- Ant Task for YUICompressor - an Ant task that uses YUICompressor to compress JavaScript and CSS files.
- JSMin - similar to YUICompressor but only minifies (remove whitespace and newlines) JavaScript files and does no compression at all. An advantage of JSMin over YUICompressor is that its faster and can be used at runtime to minify JavaScript, while YUICompressor is most often used at build time.
- Article explaining how to use Ant and YUICompressor for compression.
- Article outlining how to use a special YUICompressor Ant Task for compression.
Click makes use of the utility class PageImports to include the CSS and JavaScript. PageImports exposes the method setInitialized(boolean), which controls when PageImports are fully initialized. Once PageImports have been initialized, no other CSS and JavaScript will be included.
Knowing this one can override Page.getPageImports(), and import the necessary JavaScript and CSS files and then set PageImports to initialized, forcing PageImports to skip other CSS and JavaScript files.
Here is an example of how to apply this in Click:
public class HomePage extends Page {Using the following Velocity border-template.htm:
private Form form = new Form("form");
public void onInit() {
form.add(new DateField("date");
addControl(form);
}
public void getPageImports () {
PageImports pageImports = super.getPageImports();
String contextPath = getContext().getRequest().getContextPath();
String cssInclude = contextPath + "/assets/css/home-page.css";
pageImports.addImport("<link type=\"text/javascript\" href=\""
+ cssInclude + "\"/>");
String jsInclude = contextPath + "/assets/js/home-page.js";
pageImports.addImport("<script type=\"text/javascript\" src=\""
+ jsInclude + "\"></script>");
// Set pageImports to initialized so that no other CSS and JavaScript files will be included.
pageImports.setInitialized(true);
}
}
<html>
<head>
<title>Click Examples</title>
${cssImports}
</head>
<body>
...
${jsImports}
</body>
</html>
the rendered HTML will include one CSS and one JavaScript import:
<html>A live demo is available here
<head>
<title>Click Examples</title>
<link type="text/css" rel="stylesheet" href="/click-examples/assets/css/home-page.css"
title="Style"/>
</head>
<body>
...
<script type="text/javascript" src="/click-examples/assets/js/home-page.js"></script>
</body>
</html>