How can I speed up webpage loading using Java Servlets?
After the article titled How does
Google serve up its webpages so fast was published, many
readers sent in emails asking me: "Okay, now I know Google
shortens the loading time by compressing outgoing data. So
what? How can I make MY WEBSITE run faster?".
In this article, we are going to discuss how you can speed
up your website using Java Servlets. So, if you are running
a servlet container (e.g. Tomcat, JBoss, Resin...etc), read
on!
Before we delve into the code, I strongly suggest
you seriously read the article -- How
does Google serve up its webpages so fast if you haven't
already. It gives you the background information about how
the HTTP protocol works and how the loading time is shortened
by making use of the GZIP compression. The screenshot of HttpRevealer
is included here for easy reference:

From the aforementioned article, you learned that the prerequisite
of using the compression is that the user's browser must be
capable of decompressing GZIP data. How can we check for that?
It's a piece of cake. In your doGet or doPost method, do the
following:
...
...
// Get the "Accepting-Encoding" header from the HTTP request.
// Note that request is an HttpServletRequest instance
String encoding = request.getHeader("Accept-Encoding");
boolean supportsGzip =false;
// Now, check to see if the browser supports the GZIP compression
if (encoding != null) {
if (encoding.toLowerCase().indexOf("gzip") > -1)
supportsGzip = true;
}
...
...
|
The next thing to do becomes obvious. If the user's browser
supports GZIP, you then set the Content-Encoding header to
"gzip". And then, you gzip up the data and pump it out to
the ServletOutputStream:
...
...
// Set the response header.
// Note that response is an HttpResponse instance.
response.setHeader("Content-Encoding", "gzip");
// Assuming you have stuffed all the HTML data
// in a StringBuffer sb, let's pump everything
// in the StringBuffer to the ServletResponse's
// OutputStream via the GZIPOutputStream
try {
// remember to import java.util.zip.GZIPOutputStream
GZIPOutputStream gzos =
new GZIPOutputStream(response.getOutputStream());
gzos.write(sb.toString().getBytes());
gzos.close();
} catch(IOException ie) {
// handle the error here
...
}
...
...
|
For the sake of completeness, you would come up with something
like this in your Servlet:
...
...
import java.util.zip.GZIPOutputStream;
import java.io.*;
...
...
public class MemberListing extends HttpServlet {
...
...
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
...
...
// Get the "Accepting-Encoding" header from the HTTP request.
// Note that request is an HttpServletRequest instance
String encoding = request.getHeader("Accept-Encoding");
boolean supportsGzip =false;
// Now, check to see if the browser supports the GZIP compression
if (encoding != null) {
if (encoding.toLowerCase().indexOf("gzip") > -1)
supportsGzip = true;
}
...
...
if (supportsGzip == true) {
...
...
// Set the response header.
// Note that response is an HttpResponse instance.
response.setHeader("Content-Encoding", "gzip");
response.setHeader("Content-Type", "text/html");
// Assuming you have stuffed all the HTML data
// in a StringBuffer sb, let's pump everything
// in the StringBuffer to the ServletResponse's
// OutputStream via the GZIPOutputStream
try {
// remember to import java.util.zip.GZIPOutputStream
GZIPOutputStream gzos =
new GZIPOutputStream(response.getOutputStream());
gzos.write(sb.toString().getBytes());
gzos.close();
} catch(IOException ie) {
// handle the error here
...
}
} else {
// You output ordinary HTML here
// when GZIP is not supported by the browser.
...
} // end if (supportsGzip == true)
...
...
} // end doGet
|
Thanks for reading thus far. You may now have another question:
"That sucks! It means I have to re-write all my servlets
in order to speed up my website. What if I want to shorten
the download time of my HTML files too?". Calm down, dude.
This article only explains to you the concept of how the GZIP
compression can be used in Servlets. In real world implementation,
you can use the above concept to create an abstract servlet
which ALL other servlets extend. Then, in each concrete servlet,
you just invoke a method, say smartOutput(), to get the data
out appropriately.
Yet, the suggested implementation is still ugly. But, I calmed
you down a bit, didn't I :) Seriously, a clean way of doing
it would be to take advantage of Filters in servlet containers.
Check out Sun's "The Essentials of Filters" for more details:
http://java.sun.com/products/servlet/Filters.pdf
Okey Dokey. That's it. I hope you enjoyed the discussion.
The idea of this article was inspired by Google and made possible
with the help of HttpRevealer.
You can explore the web yourself too! [See
more info]
Steven Chau
Go back to the Index of Articles
"Java" is a registered trademark of Sun Microsystem
Inc.
All other marks are properties of their respective owners.
|