Server-side RIA framework
RIA doesn't need to be client-side. Server-side, if properly implemented, actually offers huge advantages to developers and end users alike.
Web page reloads are so retro, so 90s. While acceptable for content, they are serious hindrance for apps. Especially when you are trying to migrate users from desktop apps or compete with new smartphone apps. RIA (rich internet application) comes to the rescue. Partially so. It can indeed deliver interactivity of native apps, but it comes at the cost of low productivity and all the javascript results in poor performance on low-end devices.
There's another concept that I believe to be the future of the web: server-side RIAs. The trick is that websocket allows server-side scripts to remotely control the client. Javascript is no longer needed for interactivity, at least not much of it. I've asked on StackOverflow for state-of-the-art implementations of server-side RIA and, after a week of weeding out irrelevant answers, someone mentioned Vaadin. I will get back to that one in a moment, but let me first restate why I am looking for something server-side.
5 promises of server-side RIA
Although frequently dismissed as a crutch for former desktop developers, server-side RIA has some serious advantages:
- Productivity: No application logic duplication on client and server. No client-server API design. No client-side debugging. Everything is tightly integrated in cozy environment of the application server. Since we are no longer tied to javascript, we can select more productive development platform with as many libraries as we wish while maintaining perfect compatibility on the client.
- Security: Client-server APIs usually aren't well designed and they are almost never audited for security issues. Server-side RIA exposes only the UI to the client, which leads to much smaller attack surface that is much better tested and much more thought about.
- Compatibility: Client-side RIAs stress the client with heavy javascript libraries that ask for a lot of advanced javascript APIs. This results in sluggish performance on low-power devices or outright failure to display the page. Client-side RIAs are often so slow as to bring down desktop browsers. Server-side RIA has minimum client requirements and thus greatest compatibility as well as performance on low-end devices.
- Initial load time: Since server-side RIA has no need to send boatloads of javascript to the client, no need to JIT-compile the javascript, and no need to query client-server APIs before anything is displayed, it can deliver the landing page lightning fast.
- IP protection: Source code is a secret kept on the server. Data cannot escape in bulk though misdesigned client-server APIs.
Dispelling misconceptions and worries
There is some existing criticism of the server-side RIA concept and some of it is actually true for Vaadin. We better learn from the soft feedback before we crash into hard feedback. Let me take the issues on one by one:
- Server RAM: I think this really depends on how the server-side framework is designed. If all session state is stored under session ID in a lightweight database, there is really no data that would have to be tracked by the RIA framework. The page can be fully regenerated from the stored session data. HTML streaming (which usually sends only HTML diffs) can be restarted by sending full page update to the client.
- Bandwidth: While there will be a bit more traffic with server-side solution, it is nowhere near demands of video streaming. There's abundance of bandwidth on both client and server that's more than sufficient for our text-only transfers.
- Latency: Just how fast can the server-side RIA be? Server-side page generator coded in Java or C# can be expected to respond in milliseconds. Database (or its cache) is located right next to the application server, so data access latencies are essentially zero. Client-side runtime is minimal and heavily optimized. So it's up to network round-trips. With websocket, we have single round-trip per interaction. Most apps are language-specific and consequently region-specific, which means negligible RTT well below 50ms. Global sites can either live with 130ms average Internet RTT or replicate themselves on every continent, yielding RTT below 50ms.
- Expressiveness: Client-side RIA is theoretically more expressive and this is also practically true in some niche scenarios. Nevertheless, server-side RIA can be extended with purpose-built client-side widgets while keeping the rest of the application on the server. It's not necessary to move whole application to the client just to get some special effect working.
- Offline use: This is a real problem, because once one gets used to the comfort of server-side environment, it is next to impossible to port the application into the restrictive client environment. Nevertheless, I believe we will eventually reach a point in history when network connectivity will be ubiquitous and as reliable as electricity. Meantime, existing connectivity is good enough to provide top service to a large majority of users. Apps that really do have to run offline can just package embedded version of the server and run it all on the client.
Vaadin
Vaadin is nice, but...
- It insulates me from HTML/CSS rather than embracing existing standards as presentation/layout layer. This results in weird limitations and rendering issues. Paradoxically, it forces development of custom client-side widgets in way too many ordinary scenarios.
- Everything is javascript, even the initial page load. This leads to poor SEO and long load times on first request.
- It creates heavy and deep DOM without good reason. This cripples client-side performance and causes styling and widget authoring headaches.
- It's a memory hog. This will limit scalability to really, really small deployments, especially when people leave inactive sessions hanging around.
- Its eventing and data binding mechanisms encourage programmers to leave memory leaks everywhere.
- Binding and templating is verbose and very unproductive. We need something concise and heavily automated.
- It's big and complicated, because Vaadin is business rather than community project. Chances are that I or my employer would be pressured to pay for the non-free version.
7 principles of server-side RIA design
I don't want to give up on the idea, but I cannot use Vaadin as is. I guess I will have to come up with something of my own. Here's my plan:
- Embrace HTML/CSS: No complicated widgets. Merely enable data-driven templating of HTML. Don't mess with CSS at all. CSS should be static resource outside of the DOM.
- Assume latest technology: HTTP 2.0 instead of resource bundling. Websocket instead of AJAX and long polling. CSS3 instead of JS tricks and HTML boilerplate.
- Semi-static pages: Send fully constructed DOM on initial load. Setup javascript & websocket in the background. Only subsequent interactions are performed RIA-style. Provide hard URLs for links alongside event handlers for SEO & basic accessibility.
- Session hibernation: Inactive sessions are serialized into fast embedded database, then rehydrated upon user or internal event. This will enable endless scalability even with long-lived sessions.
- No boilerplate: Auto-wire data bindings and event handlers. Auto-wire dependency tracking for computed values. Auto-wire persistency for view state.
- Strong content authoring: Integrate Sass and static templating systems. Reference static templates from dynamic Java templates and vice versa. Interactive development with automatic page reload upon resource or code change.
Nice theory, but where's the code?
When I originally wrote this article, this was all just in my head. There was no actual implementation. I have since developed PushMode that incorporates most of the ideas mentioned in this article. It is still experimental, but I have developed several sites with it already. including the one you are reading now. You can give it a try. It might very well be that breath of fresh air you have been looking for.