Applying YSlow performance improvements within SAP NetWeaver

Having just finished reading Steve Souders’ High Performance Web Sites, I thought it would be helpful to point out how some of the server-side rules can be configured on SAP NetWeaver.

PS: Buy the book! It’s short and to the point, and very well written. I’ve already ordered his follow-up book Even Faster Web Sites to be delivered today!

The book covers 14 rules for improving performance on web sites, concentrating  mostly on front-end optimisations that can dramatically improve the responsiveness and user experience of your site. However, some of the rules involve changes on the server – for example, enabling gzip compression. The full listing of the Yahoo! Performance Rules can be found here.

Below is a brief summary of how to configure some of these rules in SAP NetWeaver. I’m using NetWeaver CE 7.1, so you may need to adjust these slightly if you’re running a different version. All configuration is done within NetWeaver Administrator > Configuration > Infrastructure > Java System Properties > Services, so I’m only going to mention that once to avoid repeating it many times over. I’ve also made an effort to reference the SAP Help docs that I’ve used to compile this summary, which you should find at the end of each section.

Rule: Add an Expires or a Cache-Control Header

The first thing to point out here is that NetWeaver has two cache control settings: one for the server and one for the client. Before understanding how to configure each of these, you need to know what it is that you’re configuring and the implications of the changes you’re about to make. I’ve included a diagram from the relevant SAP Help page (full reference below) to show the architecture of the ICM Server Cache.

The full explanation that accompanies this diagram can be found here: https://cw.sdn.sap.com/cw/docs/DOC-107069

Right… now that you have a better understanding of how caching works on the server, you’re ready to configure it. I assume you’re already familiar with the standard HTTP Cache-Control header, but refer you to the full explanation here if not: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9

In order to change the cache configuration, you need to find the HTTP Provider Service in NetWeaver Administrator and modify the following properties:

SapCacheControl – This should be set to the expiration period (in seconds) of the cached resource.
CacheControl – This can be set to any of the cache-response-directive values specified in the HTTP Specification (see link above for a reference to the section on Cache-Control).

You could argue that the server-side cache isn’t exactly what Steve Souders was talking about in his book – but when reading the documentation on the SAP Help site, you’ll see that the SapCacheControl value is also used as the Cache-Control max-age response directive… so it will have an impact on the cache status of web resources.

SAP Help Reference: https://cw.sdn.sap.com/cw/docs/DOC-100645

Rule: Gzip Components

Enabling gzip compression is fairly straight-forward. Just find the HTTP Provider Service in NetWeaver Administrator and modify the following properties:

AlwaysCompressed – This is a list of all the file extensions or MIME types that should always be compressed.
NeverCompressed – This is a list of all the file extensions or MIME types that should never be compressed.
CompressedOthers – Boolean value to indicate whether all other file extensions or MIME types (i.e. those not listed in either AlwaysCompressed or NeverCompressed) should be compressed.
MinimumGZipLength – Specifies the minimum size required for gzip compression to be applied. This property works in conjunction with AlwaysCompressed and CompressedOthers (i.e. the resource must be listed for compression AND larger than MinimumGZipLength in order to be compressed).

Note: File extensions must be in the format “*.ext”. Any entries without an asterisk will be treated as MIME types.

SAP Help Reference: https://cw.sdn.sap.com/cw/docs/DOC-111485

You can also dynamically enable compression for Servlet / JSP responses by passing special headers in the response. These headers are not sent to the client, but rather instruct the HTTP Provider Service to compress the response before sending it on to the client. These headers override the HTTP Provider Service configuration described above. If specified, the presence of these headers will force the HTTP Provider Service to either compress or not compress the response – regardless of what is configured elsewhere.

The header values themselves are configurable within the Web Container Service, and are described as follows:

HeaderForCompression – Specifies the header name that must force compression when present in the response
HeaderForNoCompression – Specifies the header name that must prevent compression when present in the response

To use this in your Servlet / JSP, simply set the relevant header to “true”.

SAP Help Reference: https://cw.sdn.sap.com/cw/docs/DOC-100076

Rule: Configure ETags

ETags are very elusive within the SAP Help docs. Despite much trawling, I could only come up with a few minor references to indicate that it exists – however no details could be found. I did find a SAP Note that mentioned a fix to ETag functionality in NW 7.0 – see Note 1020365.

If anyone manages to come across more information on this, please post a comment. I’d be interested in finding where it can be configured.

Criticism

While making all these configuration changes, it’s not hard to see that NetWeaver Administrator is lacking the user-friendliness that it should offer to administrators. It a fairly poor means of managing a system as it has been built to be as generic as possible. Unfortunately, in this case it means that there’s a lot it just doesn’t do very well because it’s trying to cater for everything in one go. To illustrate my point, simply try to modify the list of MIME types within the HTTP Service (see Mime property). This list is likely to be very long, regardless of how you configure it. What do you do if you want to add one extra MIME type? Well, in that case you need to copy the list already there and paste it into Notepad, add the item you want, then re-insert the entire list into an input field only wide enough for about 20 characters. To put that into perspective, the default list of MIME types is just under 4000 characters long. Not only is the input field far too small, but surely an administrator should be able to modify the existing list rather than recreating it to make a small change? Even worse than this is the fact the modified property text is not wrapped in the table cell. So if you do decided to add a MIME type, you lose all visibility of what has been configured as you can only see the first few characters before they disappear. I can’t say I’m surprised though. Usability has never been something that SAP do well… or at all, for that matter. However, taking visibility of the configuration of a system away from the administrator is a very dangerous thing to do. This issue very clearly illustrates how poor usability can have very far reaching consequences, and why it is so important to get it right!

This is by no means a comprehensive review of the how’s and why’s of each of these rules, nor does it go into much detail about each system property described. I intentionally kept this fairly straight forward so it can serve as a reference guide, and have instead provided links to more detailed documentation wherever I can. After all, the links are where I got the information in the first place – so it’s only right to give the original author full credit for it. I’m just hoping to save some of you time in finding the right resources.

I hope this has been helpful, even if it was nothing more than a prompt to look into other areas where NetWeaver can be configured to operate according to what you need.


Thoughts on Joining an Open Source Project

Since starting my career as a software developer back in 2002, I’ve wanted to join an open source project. A few things have held me back from doing this… including inexperience in my early career, lack of available time to commit properly to a project, and the inherent difficulty in finding that one project amongst the thousands out there that I feel strongly about. Over the last few weeks I’ve been looking into this again and have now decided to join OpenMRS. The experience of choosing a project and getting stuck in has prompted me to write about why I did it and hopefully spark some new ideas for other developers wanting to get involved in open source projects.

Why join an open source project?
Everyone has the capacity to get involved in something and help out, and software developers are no exception. I’ve always been involved in building software for business use, which has a lot of challenges and rewards – but it doesn’t really improve anyone’s life in any significant way. My reason for joining an open source project is to contribute to something that really matters… something that might genuinely improve the lives of other people. For this reason, I’ve focused on finding a project that has this as one of its core objectives.

Why OpenMRS?
The answer to this question is pretty simple… I have fairly limited “free” time as it is, so I wanted to make sure I join a project that I believe in. OpenMRS is clearly focused on providing software that can improve the lives of millions of people – particularly in the developing world – so this immediately caught my attention. My original career plan was to study medicine and become a surgeon, but after finishing school I made the decision to study software engineering instead. I don’t regret that decision, but I’ve never lost my interest in medicine, and joining the OpenMRS project gives me the opportunity to work in both.

What’s next?
When joining any new project there is always a lot to learn. Others may have been involved for years, but you have to learn the ropes before you can be of any use to the existing team. So my focus for the next few weeks will be to learn about OpenMRS from every conceivable perspective. What problem is the system trying to solve? How does it work for the user? How has it been designed? How is the data model structured? However, the biggest challenge will be gaining enough understanding of the medical domain for the system to make sense. Very fortunately, the technical foundation is quite familiar territory – so the biggest obstacle is domain knowledge.

I’ll follow up in the coming weeks with some details on how to contribute to an open source project – entirely based on my experience, rather than a definitive list of “do’s and don’ts”. Until then, I’ll be buried in documentation!