Wednesday, October 12, 2011

Java web frameworks: how to choose?

On every web project I've worked on, the discussion what web framework to use rises at an early development stage. In my experience, team members often have strong opinions on this particular subject. "JSF sucks, JSF2 is nice though, let's use it because it is a standard"; "Spring MVC worked really well at my last project, I will not settle for anything else"; "My friend says Wicket is cool and now I really want to try it". Often these claims are driven by personal preference based on immediate experience, or worse, resume building tactics. This can lead to anything between a passionate discussion and a flame war. How can we create some consensus on a selection, that is in the customer's best interest?

Website families
The first question to answer is "What kind of website are we building?". On one end we have resource based web applications. We can browse them to read news, shop for products, connect with friends, listen to music, etc. Typically we use REST style URLs to identify resources. The content on the page can be related to the URL. Typically these websites are build with frameworks that stay close to the HTTP request-response cycle (e.g. Spring MVC or Struts 2).

On the other end we have (single page) rich internet applications to handle email, process documents, create mashups, etc. The application typically has complex interactions and a rich model. The URL is often used as a single entry point into the application and is not necessarily in sync with the state of the application on the screen. Although these kind of applications can be created with the same HTTP request-response oriented frameworks, a component based framework (e.g. Wicket, JSF, GWT, Vaadin) is usually preferred to reduce developer complexity and improve maintainability of the code.

Assessing features
When building a new website it is important to discuss general features to assess the consequences of choosing an approach before even mentioning possible frameworks. This gives the team focus and often rules out quite a few options.

Following below are ten items worth checking before starting to talk about specific technologies. Especially when you are considering a component based framework, make sure you can accept all trade-offs.


1. Caching resources
Pages or partial updates loaded with a GET request can be cached by the browser or a proxy. This will decrease load on the server and improve performance on the client. A lot of component based frameworks rely on POST operations for interaction, so be sure to check this.


2. Session size
Is it always required for the user to have a session? How many users do you expect? Component based frameworks maintain a lot of state information for each user, just to function correctly. Usually this data is stored in the session. The amount of data is largely based on the complexity of a page, but I have seen instances where over 1Mb of session data was stored per user, in an application largely optimized to minimize the memory footprint.

Some frameworks offer an option to store this state in the client to reduce memory requirements. This puts a heavy load on the infrastructure though. For every request this state needs to be send to the server using POST, where it is decoded (Base64) and decrypted (security). On response the state is encrypted and encoded again and send back as part of the HTML.

Make sure there are no bad surprises here, that your framework can easily support the expected number of users on the available infrastructure. When unsure, do some proof of concept before committing to a solution.


3. Page size
Some frameworks generate a lot of HTML or rely on huge amounts of Javascript, often in an obtrusive way. This can lead to large, complex pages, frustrating users with low speed connections. The complexity of the page can also have a huge impact on rendering time. Always check if what your framework is generating is acceptable.


4. Styling requirements
When building a web site, separating markup (HTML), style (CSS) and behavior (Javascript) is considered good practice. Following some guidelines developers have maximum flexibility styling a website. When generating HTML using a framework, sometimes styling is mixed in with the generated markup. This can lead to problems when the website needs to be 'pixel perfect' in relation to the original design.


5. Quality components
Many frameworks offer components. Date selectors, autosuggestion fields and ajax forms are some examples of out of the box functionality. Having high quality components can reduce development time a lot. Make sure though that the offered behavior is acceptable to the customer. If not, check the required effort to change it. Telling your customer you can't fix a bug because the framework doesn't easily allow it gets old really quickly.


6. Client support
Even today, developing websites for multiple clients can be a pain. There are some good options like jQuery to make your Javascript cross browser compatible. What does your framework offer and how? Does it solve styling incompatibilities as well? Does it support al browsers? Does it use feature detection or browser detection? I've seen a case where all generated sources where dependent on the user agent string from the client. If the framework didn't recognize a specific user agent it would cause an internal server error, causing a lot of headaches for the developers every time a new browser was released (which is quite often these days).


7. Progressive enhancement
The term progressive enhancement refers to a strategy to build websites in a way so that all users have access to the basic functionality of the site. A lot of component based frameworks rely heavily on Javascript though, basically ruling out all clients without Javascript support enabled. Make sure the requirements of the framework are in line with the customer's expectations.


8. Bots
There are a lot of bots on the web. How are your pages interpreted by search engine spiders for example? Do they index your content correctly? Perhaps you can make a sitemap? What about other crawlers? Do you want to encourage other sites to scrape our content? Just some thing to consider when looking at the generated pages.


9. Pretty urls
On some projects I've had the specific requirement to use pretty urls for pages available to the public. Most component frameworks generate very cryptic urls. A lot is possible with rewrite rules, but make sure to check if this is a requirement and how this can achieved.


10. Browser functions
Every browser has a back button, and people will use it. If I want to go back to a previous page, I mostly use the back button, ignoring any option an application provides. I should know better, but still I expect it to work, and very often it does. I find a lot of developers to be annoyed with the back button. They keep complaining that it is a stupid function and shouldn't be used. If it is important to your customer though, better make sure your framework can support it. Same goes for bookmarking, or copying links from you address bar to share.

Final thoughts
There are probably more things to consider, comments are very welcome. Usually it is quite easy to agree on the requirements mentioned in the previous paragraph and explain them to the customer. When the boundaries are set it will be a lot easier to agree on a framework. People are very often aware of limitations or they can be looked up quickly. When there are multiple options left, factors like standardization, developer availability, learning curve etc. can be considered as well.

Sometimes people ask me why I don't like component based web frameworks, because for some projects a lot of trade offs have to be made and my argument is very much against using them. The point is not that I don't like them. In past projects I've used several frameworks like JSF or Vaadin to great success. I also worked in some projects where using a component based framework would have been a better fit. If you are building a resource oriented web site or expect high volumes of traffic, I seriously doubt a component based framework to be a viable option though.

To wrap up, I think it is a good idea to document the decision making process. Briefly write down the weighted factors and trade offs. When new developers are added to the team or unforeseen problems arise it is good to look back why a certain approach was chosen. This can greatly help accepting a limitation or speed up a reassessment.