Matt RaibleMatt Raible is a Web Developer and Java Champion. Connect with him on LinkedIn.

The Angular Mini-Book The Angular Mini-Book is a guide to getting started with Angular. You'll learn how to develop a bare-bones application, test it, and deploy it. Then you'll move on to adding Bootstrap, Angular Material, continuous integration, and authentication.

Spring Boot is a popular framework for building REST APIs. You'll learn how to integrate Angular with Spring Boot and use security best practices like HTTPS and a content security policy.

For book updates, follow @angular_book on Twitter.

The JHipster Mini-Book The JHipster Mini-Book is a guide to getting started with hip technologies today: Angular, Bootstrap, and Spring Boot. All of these frameworks are wrapped up in an easy-to-use project called JHipster.

This book shows you how to build an app with JHipster, and guides you through the plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks so you understand the underpinnings of your great application.

For book updates, follow @jhipster-book on Twitter.

10+ YEARS


Over 10 years ago, I wrote my first blog post. Since then, I've authored books, had kids, traveled the world, found Trish and blogged about it all.

Improving AppFuse's PageSpeed with Apache

One of the most important things when developing webapps is to make them fast. With AppFuse, we've tried to incorporate many of the 14 rules for faster-loading websites. We had a gzip filter before it was cool (2003) and replaced it with the one from EhCache. However, users experienced issues with both of these, both with XFire/CXF and WebWork/Struts 2 and JSPs. Because of these issues, we disabled gzipping a few releases ago.

This article is designed to show you how you can make your AppFuse webapp faster, without modifying any code. The good news is this applies to any webapp that you can deploy behind Apache.

Last Friday, I sent an email to the good folks at Contegix to see if they could install mod_pagespeed on the Apache server that sits in front of *.appfuse.org. My goal was to improve the YSlow and PageSpeed scores of the apps hosted on demo.appfuse.org. I discovered they were getting a dismal score of 24 and figured we could do a lot better. mod_pagespeed speeds up your site and reduces page load time by automatically applying web performance best practices. It seemed like an easy solution.

Unfortunately, we were unable to use mod_pagespeed. From the guys at Contegix:

Attempting to install mod_pagespeed as you requested, we find that it requires Apache httpd 2.2 and libstdc++ 4.1.2, both of which are unsupported in RHEL4. To get mod_pagespeed to work on your present operating system basically means re-rolling the core components, which would make them unsupported. I'm afraid mod_pagespeed is simply not an option on your present configuration.

Since I still wanted to improve performance, I opted for another route instead: using mod_deflate (for gzipping) and mod_expires (for expires headers). I also turned on KeepAlive as recommended by PageSpeed Insights.

mod_deflate
mod_deflate was already installed in Apache (version 2.0.52), so all I had to do was configure it. On RHEL4, Apache is installed at /etc/httpd and there's a conf.d directory that contains all the configuration files. I created a file at /etc/httpd/conf.d/deflate.conf and populated it with the following:

#
# mod_deflate configuration
#
<IfModule mod_deflate.c>
    SetOutputFilter DEFLATE
    
    AddOutputFilterByType DEFLATE text/plain text/html text/xml text/css application/xml application/xhtml+xml application/rss+xml application/javascript application/x-javascript
    
    DeflateCompressionLevel 9
    
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    
    DeflateFilterNote Input instream
    DeflateFilterNote Output outstream
    DeflateFilterNote Ratio ratio
    
    LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
    
</IfModule>

At first, I had separate lines for all the different content types (as recommended by this article). The Contegix support crew figured out the solution (everything needed to be on one line) in 14 minutes, updated the config and verified it worked using an http compression testing page.

mod_expires
mod_expires was already installed, so I added a config file at /etc/httpd/conf.d/expires.conf. I used this howto and asked Contegix for help when it didn't work. Their response took quite a bit longer this time (49 minutes), but they once again figured it out:

It appears that FilesMatch does not like to play will JkMount. It does work using content type.

My final config for expires.conf:

<IfModule mod_expires.c>
    ExpiresActive On
    
    <FilesMatch "\.(jpe?g|png|gif|js|css)$">
        ExpiresDefault "access plus 1 week"
    </FilesMatch>
    
    ExpiresByType image/jpeg "access plus 1 week"
    ExpiresByType image/png "access plus 1 week"
    ExpiresByType image/gif "access plus 1 week"
    ExpiresByType text/css "access plus 1 week"
    ExpiresByType application/javascript "access plus 1 week"
    ExpiresByType application/x-javascript "access plus 1 week"
</IfModule>

I used "1 week" because we're changing things quite a bit right now and we haven't integrated resource fingerprinting yet.

KeepAlive
The last thing I did to improve performance was to turn on KeepAlive by editing /etc/httpd/conf/httpd.conf and changing Off to On.

#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On

Summary
As a result of these changes, our PageSpeed score went from 24 to 96 and YSlow went from a 90 to a 98. When I started this experiment, I was only trying to fix demo.appfuse.org. However, it also improved the speed of all the other *.appfuse.org sites, including Confluence, Bamboo, JIRA and FishEye. Thanks for all the help Contegix! There's a good chance you've given me back a few minutes in each day.

Originally posted on the AppFuse Blog.

Posted in Java at Dec 04 2012, 09:25:05 AM MST 7 Comments