Thursday, 27 November 2008

ZK - First Impression

I first heard of ZK from several developer forums, where one of the authors of ZK posted articles comparing ZK with GWT trying to prove that ZK was superior. Ever since then, I have been wanting to learn/use ZK for several months now.

I was pleasantly surprised by the maturity and high quality of ZK from the first moment I started using it - I didn't expect it to have a drag-and-drop graphical editor - something that not many free web frameworks have out of the box. I believe it is a real contender of GWT.

The praises of ZK can be found easily and I will not repeat them here. Instead, I will outline the reservations that I have about ZK hoping to get advices from the community.

ZK Studio Installation

When I followed download instructions on ZK site to install the ZK Studio directly from Eclipse, it turned out to be an older version of the plugin. It took me a while to find out why my ZK Studio did not have the ZUL Graphical Editor mentioned in the documentation. I had to download the plugin (v0.9.x) and install it onto Eclipse manually.

ZUL Graphical Editor

The ZUL Graphical Editor is not really an editor at the moment. It only serves as a previewer. I believe ZK team is actively working on improving the editor right now.


I am not aware of any special debugger for ZK. If something goes wrong, I have to inspect the web server's log file to get the stack trace - cannot jump to the line of source code automatically. Moreover, if the error occurs at the ZUL script, the trace shows BeanShell exceptions, which can be harder to locate the real position of the error in the ZUL file.

Centralised ZScript File

I understand that zscript can be isolated in its own file and be included into the .zul file, so that the script is not littered in the presentation code. However, I find that to completely separate the script and the ZUL code is not practical. For example, to specify the a renderer for a component, I need to instantiate the renderer and assign it to a variable, then put the variable to the components renderer attribute. For example,
import com.laws.address.zk.*;

renderer=new AddressRenderer();
   <listbox id="crudAddressList" mold="paging" pageSize="10" 
    <listhead sizable="true">
     <listheader label="ID" width="30px"/>
     <listheader forEach="${afts}" >
      <attribute name="label">${}</attribute>

However, the bit of script that instantiates and assigns the new renderer cannot be separated into another file (unless a function is created to do it, which looks odd and impractical).

Event Handling

The event handling in ZK is strange - the sender has to specify the target for the event. The whole idea of events is so that the sender (or publisher) is not aware of who is going to consume the event, or how many consumers, and what the consumer will do with it. But in ZK, the target of the event is specified up front by the sender - i.e. the sender knows who should receive the event. I shall elaborate this point in another post in more detail.

To be fair, ZK does allow the target of the event to be null when posting an event. However, the event is only accessible from top-level components in this scenario.

Server Round Trips for Static Contents

Unlike GWT, even static contents in ZK will involve server decision (a bit like Echo 2). For example, upon clicking a button or menu, my application pops up an 'About' message box displaying static contents. The processing of the button click and the display of the message box involves the server and incurs a round-trip to the server. This certainly has performance penalty and puts presentation logic and load onto the server (which, IMO should be placed in the client tier - i.e. the browser). I know, there has been debate about whether the GWT way is better. I personally prefers the GWT way - especially considering it is broadband era now.

Overall, my experience with ZK has been quite positive. I think it is among my top 3 web RIA frameworks.


Zodiac said...

I use a lot of zscript (and don't notice any performance degrade), but, in your example, you can use <?init?> or apply to do the trick.

<?init class="foo.AddressPrepare"?>

Then, you can prepare the variables and store them in Namespace.

Robbie Cheng said...

Great! forwarded to Dzone. Looking forward more articles!