JSF is a great framework. Nonetheless it could be a whole lot simpler. That’s what BabbageFaces does for you: it’s a JSF 2.2 plugin addressing a particularly nasty issue. It allows you to reduce the complexity of JSF views, making JSF more efficient along the way. Every once in a while it even fixes an AJAX error.
Installing BabbageFaces is as simple as can be. Just add the Maven dependency to your project. Restart the server, run your application and you’ll see – nothing. Your application works just the way it did before. Just a little faster and smoother.
That’s because BabbageFaces works at the lowest possible technical level. It allows you to simplify your programs, but it doesn’t require you to do so. BabbageFaces optimises every JSF application out of the box, without breaking the compatibility.
Verifying your installation
If BabbageFaces has been successfully installed, you’ll see three differences:
- There’s a message in the console windows or
catalina.out(“Initializing BabbageFaces DifferentialResponseWriter”).
- Looking at the HTML source code of your browser you’ll find that manyand tags bear a couple of IDs you didn’t enter.
Many AJAX responses look different. In almost every case they are a lot shorter.
I just tried it with Glassfish, and simply copying the jar file didn’t work. So the better alternative may be to copy the jar file to your applications WEB-INF/lib folder, or to add the dependency to the POM file if you’re using Maven:
<dependency> <groupId>de.beyondjava.angularFaces</groupId> <artifactId>babbageFaces</artifactId> <version>0.1-SNAPSHOT</version> <scope>runtime</scope> </dependency>
BabbageFaces isn’t available at Maven Central, so either you have to install the jar file in a local folder or you clone the AngularFaces project from GitHub and run
In case BabbageFaces still isn’t activated you can add a line to the
<factory> <external-context-factory> de.beyondjava.jsf.ajax.context.BJExternalContextFactoryImpl </external-context-factory> </factory>
So what does it optimize?
Did you ever look at JSF AJAX responses? JSF updates views by replacing the old HTML code by a new version of the HTML code. If you’re using JSF without AJAX, the entire page is replaced. If you’re using an old browser such as Internet Explorer 6 or 7 the entire page flickers. That’s a refreshingly simple and reliable approach delivering good performance on the server side. The drawback is a mediocre performance on the client side and a lot of eye strain to users who happen to work all day long with your application.
AJAX solves the problem by replacing just parts of the HTML page. That’s a huge improvement. The drawback is a whole new layer of complexity to the application.
BabbageFaces goes one step further by replacing even smaller parts of the HTML page and by removing the layer of complexity again. I’ll get back to the latter point in a minute. Let’s have a look at the client side implementation first.
If there’s an alternative to replacing a DOM node, BabbageFaces will make use of it. You don’t have to redraw a table just because a row has been deleted. BabbageFaces detects the situation and deletes just the single row.
You can watch the effect by opening your browser’s web developer tools (or FireBug) and watching the network traffic. I’ll soon publish an article on this blog explaining in depth what’s happening. As for now, just watch the size of the AJAX responses and look out for the keywords
eval. Pure JSF is restricted to a single keyword:
But as I mentioned, you need a slow network or slow hardware to notice the effect. Chances are mobile users will feel the difference. Desktop users connected to a fast office network probably won’t, unless your JSF views are extraordinarily complex. So I believe the second advantage is more important.
The benefit to programmers
BabbageFaces allows you to program more sloppily without being punished. You can get rid of a lot of IDs. As to my experience, this amounts to get rid of a lot of mistakes, not to mention a myriad of keystrokes and the time you are distracted from solving the business problem.
JSF AJAX requires programmers to provide hints which parts of the page need to be replaced. You have to decorate a lot of JSF components with unique IDs and to add these IDs to every button, menu item, tab and every other interactive component of your page.
I’ve seen programmers using a lot of IDs in order to get more efficient AJAX. If you know a particular button influences merely two input fields, you can update them instead of updating the entire form.
That’s no rocket science, so many people use IDs without thinking twice. The problem is the IDs are a technical issue. They don’t add any benefit to your business application. They distract you from solving the task you are paid for. Even worse, they are a first-class source of errors. Just imagine the business logic changes, so the button of our example above has to update the third field. It doesn’t suffice to modify your business logic, you also have to update your JSF page.
BabbageFaces allows you to always update the entire form, no matter which part of the form has been updated. It’s up to the computer to figure out what to do. You solve the business problem, leaving it to the computer to solve the technical hassles. That’s the way it ought to be. Mind you, the computer usually is better at solving technical problems than you are. Actually, JSF only allows you to optimize up to a certain point. A low-level framework like BabbageFaces can do more sophisticated optimizations. For instance, we defined the button to update two input fields each time it has been hit. Pure JSF always updates both fields, no matter whether the values have changed or not. BabbageFaces updates only one field if the other field is unchanged. Even better, it simply updates the value instead of updating the field. Even if you chose to use
What does the name mean?
The core algorithm of BabbageFaces compares two versions of an HTML page, figuring out the differences. Thomas Andraschko baptized this module difference engine, so I decided to call the project after the inventor of the first difference engine, Charles Babbage. Actually, our difference engine is a lot less complicated than the model shown by the Wikipedia image :).
Which bugs does BabbageFaces solve?
Many AJAX clients suffer from nasty bugs caused by network delays. Sending data to the server, processing it, sending it back to the client and updating the HTML page takes some time. In most cases, it’s less than a second, but sometimes it takes more time. During this time users continue to work with the application. So it happens users start to fill fields that all of a sudden disappear. Or that are emptied after typing. In almost every case updating a form means loosing the cursor focus.
This class of error is hard to track down. Typically developers benefit from a fast developer machine and a fast network connection (i. e. local traffic that doesn’t involve the network at all), so they find it hard to reproduce the errors.
BabbageFaces reduces this class of errors by replacing smaller parts of the page. You won’t loose the inputs of a field that is not being replaced. Cursor focus won’t get lost because of the same reason. In most cases the input fields that have to be updated are fields the user has just left, so the AJAX response won’t interfere with the users actions.
Is it a free lunch?
There’s a small price tag assigned to BabbageFaces. It consumes both CPU resources and memory. In the case of the pet store demo application, this amounts to roughly 10-20% extra CPU time. I’m optimistic in many cases the reduction of network bandwidth is more important.
If CPU consumption is an issue to you, you can reduce the strain on the CPU by adding IDs to your buttons (i.e. by returning to the traditional way of programming JSF pages). By default, BabbageFaces encourages you to use the most simple solution. But of course, that doesn’t mean it forbids you to optimize manually.
In case you’re suffering from sluggish performance, please drop me a note. I’m pretty sure BabbageFaces can be tweaked a lot.
So I think the advantages outweigh the small extra cost in most cases.
BabbageFaces requires JSF 2.2 or above. In theory it should work with every JSF 2.2 component library. However, at the time of writing I only tested it with Mojarra and with PrimeFaces.
PrimeFaces users need to use PrimeFaces 5 or above.
A framework I don’t expect to be compatible is ICEfaces. ICEfaces offers Automatic AJAX, a similar optimization, so BabbageFaces wouldn’t be useful with ICEfaces, anyways. Judging from their description (I didn’t have a look at the source codes yet) their implementation is astonishingly similar to the BabbageFaces implementation. I guess there are only so many ways to do the task.
At the time of writing (January 4th, 2014), I just finished BabbageFaces. Every test I ran worked just fine, but still, I’d be surprised if there weren’t any errors left. For example I had to fix several bugs to run the JEE 6 pet store demo on BabbageFaces.
I just completed the second release candidate of BabbageFaces. I’ve tested it with my showcase examples and the PrimeFaces 5.0 showcase. BabbageFaces passed both tests without problems.
But still, please be careful if you’re using it in production. It’s very new stuff, so please test your application thoroughly. As the license says,
the program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Please feel free to open an issue on GitHub or to drop a note on this comment if you run into problems using BabbageFaces. The restrictions of the license simply state I’ll refuse to promise you to solve your issue. It doesn’t say I won’t have a look at your issue :).
I put BabbageFaces under a GPL 3 licence. Please contact me if you want to use BabbageFaces commercially.
Essentially BabbageFaces is an idea by Thomas Andraschko. He wrote the initial prototype and gave me valuable hints when I took over. Thanks, Thomas!
Do you want to participate with the development of BabbageFaces? I published the source code at my AngularFaces GitHub repository. So there are various ways to participate. You can report bugs by opening an issue on the AngularFaces repository. You can fork the source code and ask me to integrate your improvements by making a GitHub pull request. And of course, you can simply leave a comment on this blog.
Live demo on the showcase
There’s also a live demo on the AngularFaces showcase: http://showcase.angularfaces.com/babbageFaces/index.jsf. The first three tabs are very technical demos demonstrating the idea. The last tab shows a small real-live application.