In this article I describe why Wicket framework isn’t suited for websites. But I first start defining the difference between Websites and Webapps.
Websites vs Webapps:
A webapp behaves like a desktop client-server application, but it’s accessible via an URL in a webbrowser instead of as an executable on an OS. Webapps can be rendered in HTML, but also in Flash, Silverlight, Applets etc. Webapps usually don’t have content that should be indexed by search engines, so Search Engine Optimalization (SEO) plays no role in webapps.
A Website on the other hand, is less focussed on the application, but more on serving its content to users, usually rendered in HTML instead of Flash etc. SEO is usually very important.
There are far more website than webapps on the Internet, although a clear distinction between a webapp and a website can sometimes be a bit difficult. Some websites contain parts that can be seen as a webapp. The focus of it determines whether it should be called a webapp or a website. If it’s the primary goal is serving content to users, than it’s a website. If it’s primary goal is allowing users to add/control content where serving content plays a lesser role, than it’s a webapp.
Website owners often try to get as many visitors as possible, this includes search engines. Webapps on the other hand, are often internal for a company, and only want a small number of people to be able to control and view it’s content.
In this article, I’ll describe why Wicket isn’t suited for websites, and that Wicket is targeting Webapps instead.
When developing websites that primarily serve content, the unnecessary usage of sessions should be avoided when the memory costs of sessions are relatively high. However sessions are often needed to preserve state among webpages, especially when users have the ability to login at a website. So in the ideal case, when a guest visits a page, then no sessions are used, but when the guests logs in, than that same page can use sessions. With effort, to some extent, it is possible to achieve this in Wicket, but it’s difficult because Wicket is a framework that heavily depends on session state, and the session size is relatively high. Wicket does have some stateless components that can be used, but only a few exist and they are not matured. To be sessionless, all resources (pages) that are requested by the user within 30 minutes (default) should be completely stateless. If only one Wicket component is stateful, then sessions will be created automatically.
Session memory problems can easily occur when a cookie disabled client (webbrowser or bot) visits a Wicket website. These client will cause new sessions to be created at every page load/refresh. When a single page contains multiple session-state components that are requested under a separate http request as result of a single page request, then the number of sessions can explode. Especially when a bot visits the website. (But you don’t want to block bots, because if you have a website, Search Engine bots are very welcome. This is different when you have a webapp instead of a website.)
So developing (sessionless) websites using Wicket is difficult. There are only a small amount of stateless components, and they aren’t matured.
If it was possible in Wicket, then a problem that arises is how to deal with Ajax requests. You don’t want a full Wicket page to be constructed on every Ajax request.
I like Wickets, there aren’t much similar frameworks that have the same programming model. I hope the Wicket team realises that sessionless/stateless components are very important when it comes to website development in contrast to webapp development.
Updated/added at 27 January 2011:
To come back at my comment of maybe being to harsh at session usage for public facing websites, I don’t think session usage would be a big problem if the session size was small. But the session usage in Wicket is large.
(Size can be checked using RequestCycle.get().getSession().getSizeInBytes() , which has to be called after the page is fully loaded and stored in the session.)
Wicket stores almost everything in sessions for a page is stateful, even when using models. For example, when you want to render a list of String that is retrieved from the database, and render it on a stateful page, then you can use a loadableDetachableModel to retrieve the data without storing/serializing all the strings in the that model. But when you render the strings using a listview, you have to add labels to the listview’s items in the populateItem method (at least if you want to do it the Wicket way). But the labels itself will contain a model that stores the String anyway. Or you can use a compoundpropertymodel using item.setModel(new CompoundPropertyModel(item.getModel())), but that also adds extra objects to the session.
Example, if you have a list of 2253 strings, which in total is 17.5kbyte (7.96kbyte/string on average), that you want to be rendered on a stateful page, then it will cost you about 198kbyte in session usage when using the nested CompoundPropertyModel approach. It will even be larger when using a default label model. 198kbyte imo is way too much, that part of the page should be 0 kbyte.
If you have an internal webapp than you can calculate the maximum memory usage based on a fixed number of internal concurrent users. But if you have a public facing website, than calculating the maximum memory usage is hard. Public facing websites want to attract as many visitors as possible. The number of concurrent users can vary daily. It’s possible that due to linking of external websites, a website get an order of magnitude higher number of visitors the next day. Which can easily cause big problems on website that use large sessions sizes.