Cloudflare CDN (Content Delivery Network)

Best practices for web applications often call for the use of a CDN. Those of you that have worked with YSlow! are likely very accustomed to seeing warnings for this reason. I’ve found that CloudFlare is very easy to setup, and for basic services costs absolutely nothing. In addition to the obvious performance advantages of using a CDN to offload much of your network traffic, it also has the advantage of improved security.

CDN’s work by caching a copy of your static content at several locations around the world, making it closer and faster for your users.

Implementation takes only minutes as it requires that you:

  1. create a (free) account,
  2. retrieve your existing DNS values from your current provider,
  3. determine direct vs. CDN “cloud” routing for each subdomain,
  4. change your DNS records to point to the CloudFlare DNS servers

Some additional advantages I’ve seen since implementing:

  • Site remains available in limited capability to users during server outages or upgrades.
  • Simplified network configuration as all requests can be sent outside of the LAN for users local to the servers
  • IPv6 dual-stack support

REFERENCES:

Browser Performance/Capability Benchmark Testing

In the past few years the browser wars have heated up again. Performance and capabilities of some browsers varies greatly. There are several standard tests that are publicly available to benchmark your systems. WebKit (Safari, Chrome & Chromium) and Mozilla (Firefox) based browsers, as well as Opera perform pretty well, MSIE is currently trailing in most cases.

Here are a few common ones…

HTTP ETag Header

These are useful for some advanced caching behavior, but there are cases where you might find them unnecessary for static files (in particular). Most network analysis tools will call attention to this header value, and while it seems like a trivial amount of bandwidth to send from the server to the client, the real reason for the negative score is more likely related to the behaviors that it causes in the client.

It should be noted that the default value used for the ETag is based upon the ‘inode’ of the file, as such it’s IS problematic in clustered server environments. I’ve shown the correction for this below.

Adding the following to your Apache http.conf file is a start:


# Change ETag to remove the iNode (for multi-server environments)
FileETag MTime Size

#Remove ETag from all static content, this could be done globally without the FilesMatch, but we want better control.
<FilesMatch "\.(html|htm|js|css|gif|jpe?g|png|pdf|txt|zip|7z|gz|jar|war|tar|ear|java|pac)$">
<IfModule header_module>
Header unset ETag
</IfModule>
</FilesMatch>

REFERENCES:

Cheers.

HTTP Cookie Header

Obviously “Cookies” have a lot of advantages in web applications to maintain “state”, unfortunately using standard server configurations leads to even static content serving them up un-necessarily wasting some (minimal) bandwidth.

Adding the following to the Apache httpd.conf file is a start:
#Remove Cookie from all static content (except HTML as javascript could use it)
<FilesMatch "\.(html|htm|js|css|gif|jpe?g|png|pdf|txt|zip|7z|gz|jar|war|tar|ear|java|pac)$">
<IfModule header_module>
Header unset Cookie
</IfModule>
</FilesMatch>

REFERENCES:

Cheers!

Avoid CSS Expressions

MSIE5 added support for CSS expressions or “Dynamic Properties”, however MSIE8 ‘deprecated’ their use and prevents their use in Standards Mode.

While powerful because this allowed you to script your CSS dynamically, there were two primary problems.

  1. Performance – the expression could fire literally hundreds or thousands of times on a page when scrolled or resized.
  2. Security – this represented an attack vector and exposed XSS

REFERENCES:

Java final modifier keyword

I’ve been a huge fan of the ‘final‘ modifier in Java for function arguments and variables. While there’s some debate on their usefulness for performance, they definitely add in readability and understanding of code as developers are instantly notified by modern IDE’s and when they try to reassign such values as the compiler will indicate the error.

NOTE: Use of final for classes or functions often contradicts the paradigm of Object Oriented programming as you’ll be restricted from extending or overriding those items!

JSP Whitespace reduction

I’ve often found that most JSP developers are uncertain as to why their HTML output contains a lot of extra blank-lines, tabs and carriage returns. White space included in the template text of JSP pages is preserved by default. This can have undesirable effects. For example, a carriage return added after a taglib directive would be added to the response output as an extra line. This cruft is known as WhiteSpace, and it is responsible for a lot of wasted bandwidth and many spacing issues in HTML designs.

The challenge:

  • Developers that only use WYSIWYG editors are never even aware of the extra spacing within JSP source code.
  • Developers that work in source code often want to format the markup to allow for better visualization and readability of the source code.
  • Most IDE’s do not show the developers the special characters within the editor environment, external text editors such as NotePad++ and TextPad can be configured to show them.

Here’s a few suggested approaches on removing these, first development items:

  1. Remove comments:
    • Remove any (and all) JSP style comments <%-- comment --%> as each line in them will result in a carriage return being sent to the browser.
    • While you are at it, remove HTML comments <!-- comment --> as they often expose potential attack vectors for individuals trying to hack your website.
  2. Combine your JSP directives, <%@page %> or <jsp:directive.page /> into a single entry.
  3. Open and close all tags on a single line when possible.

Compiler options are possible for some platforms:

  • The page directive on each JSP can contain the argument to tell the compiler to trim the space in individual JSP’s:
    <jsp:directive.page language="java" pageEncoding="utf-8" trimDirectiveWhitespaces="true" />
  • For Tomcat (and others?) web.xml can be edited to contain the following in the jsp-config section:

    <jsp-config>
    <jsp-property-group>
    <url-pattern>*.jsp</url-pattern>
    <trim-directive-whitespaces>true</trim-directive-whitespaces>
    </jsp-property-group>
    </jsp-config>
  • For Tomcat (and others?) web.xml can be edited to contain the following for the JSPServlet:

    <init-param>
    <param-name>trimSpaces</param-name>
    <param-value>true</param-value>
    </init-param>
  • The deployment descriptor can also be used to do so by adding a trim-directive-whitespaces element to a jsp-property-group element in the deployment descriptor and set it to true.
  • Some IDE’s expose the attribute, NetBeans 5.5 uses the following:
    1. Open the deployment descriptor file in the editor.
    2. Click the Pages button at the top of the editor.
    3. Select a JSP property group.
    4. Select the Trim Directive Whitespaces checkbox.
    5. Save the deployment descriptor.
  • Custom tag authors can eliminate white space from the output generated by a tag file by setting the trimDirectiveWhiteSpace attribute of the tag directive to true.

JSP Version Matrix for common servers:

Apache Tomcat 7.0.x JSP 2.2
Apache Tomcat 6.0.x JSP 2.1
Apache Tomcat 5.5.x JSP 2.0
Apache Tomcat 4.1.x JSP 1.2
Apache Tomcat 3.3.x JSP 1.1
IBM WebSphere Application Server 7.x JSP 2.x
IBM WebSphere Application Server 6.x JSP 2.0
IBM WebSphere Application Server 5.x JSP 1.2

REFERENCES:

Happy coding!

Enable HTTP GZip compression on Apache Tomcat

This one escaped me for a long time and I never saw a decent example of it in any of the documentation.

GZip compression saves on network bandwidth as files are compressed during transport between the HTTP Server and browser/client. If you already use Apache HTTP or a similar webserver to front Tomcat, this is not always necessary, but in cases where you expose your appserver directly, even if it is just for testing, you may want to add this configuration item as it increases the perceived speed of the application.

The solution is simple:

  1. To be safe, first stop the server and backup your configuration files
  2. Look in the /TOMCAT/conf installation folder.
  3. In the ‘server.xml’ file, you will find a line resembling…
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
  4. This one controls the HTTP/1.1 connections, add a new value to the list…
    compression="on"
  5. NOTE You might also see a value for for AJP/1.3, unfortunately compression only works for HTTP:
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
  6. Restart your server.

Cheers

Apache Tomcat Native Library (APR)

If you have ever looked at the console or logs while starting a Tomcat instance on Windows you have probably seen the following line about APR.

INFO: The Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path

As long as the “tcnative-1.dll”  is in the Windows PATH, generally you can place it in c:\windows\system32, but any other location in the PATH will work should you need it to be portable, or have different versions in use.

NOTE: Other Operating Systems use a similar approach as Windows to add an environmental variable, optionally you can also add the appropriate location to the “java.library.path” attribute used when calling the VM, if you are more technically inclined. Also, be aware of 32 vs. 64 bit architectures when selecting your version!

Cheers

Windows NTFS Performance

For a very long time I was perplexed as to why my old 900Mhz Pentium-3 server outperformed many of my newer and faster machines, even when they all were running with essentially the same amount of memory and had the same 7200rpm hard-drives.

I recently realized that over the years, I had optimized the WindowsXP NTFS registry settings with a variety of software and manual edits, and thus had essentially changed the way that windows works with the drive itself.

Here are the current settings that these machines utilize, perhaps you can try them for yourselves:

WARNING: You need to be confortable making edits to your registry to do these changes, as such I will not document ‘how’ to open the registry itself, you can easily find that info anyways.  These are all DWORD settings.

HKLM\SYSTEM\CurrentControlSet\Control\FileSystem

  • DisableNTFSLastAccessUpdate  = 1
  • NtfsDisable8dot3NameCreation = 1
  • NtfsDisableLastAccessUpdate = 1
  • NtfsMftZoneReservation = 2

Cheers