Tuesday, February 26, 2008

GWT: follow-up

This is a follow-up post on Why I dumped GWT.

First of all, I had a really long week + weekend and I was tired when I wrote the post. I apologize for the rather in-your-face title. I should have chosen a more subtitle wording, especially since I really appreciate all the work that developers donate in their free time to open source projects.

I did't expect my blog post would end up as the main article on ongwt.com. I use my blog mainly to communicate with colleagues about my work. It probably has something to do with my recent switch to feedburner. Hooray for feedburner!

Like I wrote, I like GWT and its approach. It's really nice to see how intelligent the development team approached and solved the problem at hand. The image handling (sprites), js compression and http round-trip optimisations are really clever.

I'll start by describing how my site came to what it is now. The site started as a playground for me. I wanted to try the latest new thing (ajax!) and so I first started with scriptaculous. I didn't succeed in getting the layout right with pure css (after all, I'm only a Java developer) and I stumbled upon GWT. The mail app demo is really nice and this gave me the idea to start a site that searches on-line marketplaces and lets users treat the classifieds as e-mail: with the possibility to delete, mark items as read/unread and star them. Much like Google Reader.

For this, GWT was the perfect match. Everything went as I expected it to do, sometimes with some cursing about why my onclick events were not fired and why a non-existing background image in css stopped the hosted mode to work, but all-in-all it was very good.

After some (positive) discussion with my other half, I wanted the work I put in it to give me some return-on-investment (money!). It turned out after some basic user testing (she sitting at the keyboard and I shouting "why would you do that?" and "that's not meant to be used like that") that the whole idea was too complex for a standard user (no offense to my super-intelligent girlfriend) who stumbles upon my site. So week after week I removed some of the functionality to make the page less overwhelming. Until I finally found myself using GWT only for the autocompleter, which clearly wasn't the intention of the GWT framework. This, together with the remarks I gave in the previous post (adsense, analytics and seo) made me decide to temporarily stop developing with GWT.

I expect to start again with GWT once the site "gains some momentum", and then I will re-enable those more complex features which should be easier than with mootools. I'll probably ask some advice from a usability expert about how to design the page with all this functionality without overwhelming first-time users. And I will check out MyGWT and GWT-Ext more thoroughly.

Labels: , ,

Sunday, February 24, 2008

Why I dumped GWT

I've used GWT for over half a year now on koopjeszoeker.be. Two weeks ago I decided to stop development with GWT and go with plain HTML and mootools for the autocompleter. I've used mootools already a lot and I'm really getting the hang of it.

Why? Why did I spend all this time developing in GWT and why did I decided to stop?

First of all, GWT is a fantastic framework for doing web development. I think it's the best tool at the moment if you want to build the next GMail or an intranet application. For all those slow and lousy web interfaces (for timesheets, CMS, ...), GWT could come to the rescue. But my site is completely different.

Some of the reasons below are not really related to GWT, but more to using ajax in general. It is my opinion however, that these problems are easier to solve with 'standard' javascript libraries like mootools, prototype, dwr or scriptaculous since these have a nice way to add some ajax to certain DOM elements. For example, in GWT I had to subclass the autocompleter textbox so I could attach it to an input field that already existed in the HTML. Maybe all of this could by solved if GWT had constructors that accept a DOM id too.

SEO


I'm entering in a highly competitive segment where SEO is really important. Since most of the html is build with GWT, you end up with a pretty empty page for Google. I added some noscript tags, but this was not really helpful.

Adsense


Another problem were my adsense banners. Since I didn't have a lot of content on the page, the banners were sometimes off topic. An even bigger problem was that the banners stayed the same when people searched for different keywords (since the ajax refresh didn't trigger an adsense refresh). I solved this by doing the search with a page refresh instead of an ajax call. The ajax part of the site was limited to sorting, faceting, i18n and displaying tips.

Google Analytics


I'm also using Google Analytics. Although no real evidence exists, it would be naive to think that Google isn't using this data. But because of the ajax calls, I don't get as many pageviews as a static version of competing sites. Every visitor is seen as doing 1 page visit, while he may have browsed several pages. This makes my bounce rate in Google Analytics really high. This can't be good for my Google rankings.
In Belgium we have CIM Metriweb, a kind of archaic tracking system that is used when marketeers look for sites that have many hits. I'm not currently using this, but this thing depends on pageviews if you want the big guys to donate to your site.

What now?


I wanted a fully functional HTML version, where GWT was injected in some places to replace the full page loads with ajax calls. However, I couldn't find an easy way to do this. And once I succeeded, I found that I had almost no code left in GWT that was worth using it instead of mootools. So now, after a lot of research and experimenting, I decided that I'll go for the plain-old html way and spiced up some parts with ajax (like the "so 2007" textbox autocompleter).

I discovered the Blueprint CSS framework (version 0.7 now has semantic classes) and CSS sprites. I've used Kuler and read a lot about CSS tips and tricks. I even read a bit about usability.

And since I spend 3 hours a day on the train, I have time to redesign the site. Using blueprint, it really was easy and the result is a much better looking, stable, fast site. Check the homepage: it only has 1 css, 1 javascript, 1 gif and 1 jpeg, but there are 25 images! Ah, the magic of blueprint, sprites and jawr...


Update: please see GWT follow-up

Labels: , , ,

Monday, February 18, 2008

Compress Javascript and CSS with Jawr

Today I used the nice Jawr taglib which compresses javascript and css files. There's enough information on the Jawr website about how to configure everything, so I won't write about this.

Things to remember are:

  • Better structuring / versioning of your development javascript and css versions while still publishing them as 1 file

  • Gzip support for compliant browsers

  • Give the css and js files cache headers 'until the sun explodes'

  • When you deploy a new version of your site, a new css and js version will be downloaded by the browser

Net result: our YSlow score went from 49 to 69!

Labels: , ,

Sunday, February 17, 2008

2 Things I want in CSS 3

I've done some html/css restyling lately and there are some things I would like to see added to CSS 3. The process to request some changes to be incorporated into CSS 3 is a bit overwhelming to me, so I just post them here and hope they will be picked up by someone.

CSS variables


CSS variables would be nice. I want a way so I can easily change all colors in my CSS with one adjustment, not by searching for the color in the file and replacing it with the new value. I also think this would increase readability of the file.
This would allow to define recurring parts of the layout in the CSS file like this:

var backgroundcolor : #FFFFFF;
var border: 1px solid #CCCCCC;

.container {
background-color: $backgroundcolor;
border: $border;
}

.navbar{
border: $border;
}


Path variables


If I could rename a path selector to a variable, I could remove a lot of classes from the html and still be able to easily change the css.
Take this example:

.navbar ul li a {
text-decoration: none;
}

.navbar ul li a:hover {
text-decoration: underline;
}

This would become:

var listItem: .navbar ul li;

$listItem a {
text-decoration: none;
}

$listItem a:hover {
text-decoration: underline;
}


These examples look simple, but my experience is that a lot of the same values can be found in many CSS files. Wouldn't it be nice if we have a block of variable definitions at the top so we only have to specify once that the color of all borders should be changed?

This would also make it easier to let users (on a blog for example) override the colors with their own stylesheet, which overrides the variables with their settings.

The only way I know off to achieve this at the moment is by generating the CSS with a templating framework like JSP or Velocity (or why not PHP), but this seems like overkill to me.

So, anyone with the power to move the W3C board, go on (and let me know of the results)!

Labels: ,

Tuesday, October 23, 2007

Firefox add-ons

In the series "which Firefox add-ons do you need as a web developer", here's my list:
- Firebug
- Web developer toolbar
- Download statusbar

Labels: ,

Friday, October 12, 2007

Book list

I just ordered 2 new books at Amazon:

Squid, Definitive Guide
Release It!

I'm curious when they'll arrive!

For the interested: my current library (ahum):
Building Scalable Websites
Professional Java Development with the Spring Framework
Expert One-on-One J2EE Development without EJB
Hibernate in Action

I created these links to Amazon with the Amazon Affiliate program, so if you a book through this links, you're helping a poor Java developer...

Labels:

Friday, September 28, 2007

GWT and IE: The Story Continues

This is the second time I loose more than a day searching why Internet Explorer choked on my GWT application.

Finally, I replaced my whole GWT code with the latest working version, but still without result. The only difference between the working version and the broken one was the CSS file. After a boring process of commenting and uncommenting CSS lines, I found that the guilty part was this:

#content{
border: 1px solid #3F8FB6;
}


I still don't get it...

Labels: ,

Wednesday, September 19, 2007

GWT and IE: operation aborted

I got an "operation aborted" error in Internet Explorer 7, which rendered half of the page and then showed an empty page. Needless to say that everything worked perfectly in Firefox.

Even stranger was that I finally managed to fix it, but when I added Google Adsense banners, I got the error again!

After some googling and frustrating (un)commenting of blocks of code, I finally moved all javascript imports (GWT and Google Analytics) to the end of the page (just before the closing body tag). And - woohoo!- everything works!

Thanks to this overview of the problem!

Labels: ,

Monday, April 02, 2007

Spring sample project

I found a nice (and small) Spring sample project on the Interface21 Team Blog.

I learned about @NotNull annotations and how to define/process them in the applicationContext.xml. Also, this is an interesting remark I found about registering PropertyEditors:

The JavaBeans package uses a small little convention to resolve property editors. If a conversion is needed for a specific class, the JavaBeans package searches (amongst other) for a class in the same package named after the to be converted class, appended with 'Editor'. Therefore, the CarModelEditor does NOT have to be registered; it's found automatically!

I suggest you download the code and have a look at the xml and java files.

Labels: , ,

Monday, March 26, 2007

Webwerkers Blog

Samen met Frank (een collega van mijn "The Reference" periode) en enkele andere collega's is het de bedoeling om een blog voor "webwerkers" bij te houden. Mijn eerste post over HTML optimalisaties staat er al!

Labels:

Sunday, February 11, 2007

Comments in XHTML Strict

I just spent way to much time trying to find a fix for a CSS problem in Internet Explorer 7. Finally, I discovered that everything was fixed as soon as I removed a html comment from the beginning of the page.

So I changed
<!-- Start page -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

to
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

And all of a sudden, everything looks exactly as intended (and designed in Firefox).

I tried a lot of fixes, from checking javascript solutions to the Holy Grail.

Now I still have conditional comments, but this is something I can live with.

Labels:

Monday, January 23, 2006

PCTV version 2

Version 2 of Telenet PCTV has been released today (if you've read my other posts, you understand what a busy time I've had lately). Main new features are:
More exciting new features are coming, so stay tuned!

Labels: ,

Monday, January 16, 2006

Telemeter

The new Telenet Telemeter was released this weekend. Telenet is one of the two greatest Belgian cable providers. The telemeter is a tool where you can view how much data you have uploaded and downloaded. It is also possible to specify if (and when) you want to get an e-mail or a webpage when you have reached for example 80% of the monthly volume that you can download.

This project interfaces with the Telenet backend by using Hessian (we first used Axis, but since both application are written in Java, we decided to switch to Hessian in order to have a performance gain). The switch from Axis to Hessian was simply a matter of switching Spring configuration, which again indicates the cleverness of the Spring framework.

The application displays some charts. After a rather negative experience with jFreeChart and CeWolf, we decided to use FusionCharts, a flash application which uses XML to render the graphs. This choice has a lot of benefits:
  • The XML is very easy to understand and generate

  • Load is moved from the server to the client

  • It's easy to switch layout and graph type

  • The graph can contain a lot of useful information without using huge html imagemaps

  • The graphs can use animation, which give a wow-effect to the end-user

The telemeter now runs very fast (considering what happens behind the scenes) on a WebLogic cluster, but had some initial load problems because of another application that was running on the same server that crashed it.

It is sometimes humorous to read the post on the Telenet user forums, where a lot of people (mostly teenagers have nothing else to do besides downloading movies from newsgroups and complaining about the data limits) report errors which most of the time are just because of their misunderstanding of the application.

I myself am convinced that the data limits are needed so the network stays fast for everyone and isn't slowed down because some guys want to watch illegal low quality movies. But, of course, this is my own humble feeling about it.

Labels: ,

Monday, January 09, 2006

CM Site

Today the new CM site went live. I the role I played in this project was limited to optimisation of the database code (Hibernate tuning) and some small Java development. The site runs on Tridion and Oracle Application Server.

One piece I'm particularly proud of is the selection of postal codes and cities. You can try it out here. It suggest possible cities while you type, and supports both mouse and keyboard navigation. There is also a fallback on the server when the browser doesn't support (certain parts of) javascript.

Instead of cluttering the html with javascript, I wrote a .js file which registers methods like 'onmouseover' and 'onchange' to objects in the HTML DOM when loading the page. There was an issue with Internet Explorer which leaks memory when using this, so I needed a "shutdown" method which deregisters these callbacks when the user navigates to another page.

I didn't use ajax for this because it would generate to much load on the server to get city name suggestions for every letter that is typed and because the data is rather limited.

You can browse the source of the page and look for yourself how this all works.

Labels: ,

Friday, July 22, 2005

CharacterEncodingFilter

Almost daily I discover a hidden gem inside the Spring support classes. org.springframework.web.filter.CharacterEncodingFilter is one of them. The important code is only 3 lines, but it is very useful for localized applications.

It sets the character encoding of the request, which is often needed because most most browsers don't specify it. It was the solution to our problem where we got strange characters instead of the correct ones (é, è and so on ...).

<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>

Also useful to know is that this class uses the OncePerRequestFilter which is a subclass of GenericFilterBean. These classes are very good base classes for the javax.servlet.Filter interface.

If you haven't looked at the Spring source code already, you should do this as soon as possible and check this out. The javadoc is very clear, but I learned a lot by looking at how the Spring guys do it.

Labels: ,

Monday, May 02, 2005

Ajax (Advanced Javascript and XML)

I create a simple search page with the aid of some helper classes for Lucene integration in Spring and an Ajax implementation.

Ajax enables HTML to be changed with server data without the need to refresh the html or complex scripting.

The result is pretty neat: while typing, the search results are already displayed so it is easier to find something. For standard HTML sites this is probably overkill, but for the upcoming Media Center sites where a user has only a remote control available, this is quite useful.

The DWR library is surprisingly easy to use and very complete, thanks to the guys from Getahead.

Labels: