Q and A: Unexpected technical issues when contracting

I got a question from a friend who is doing some freelancing.

Perhaps an odd question, but when you do web work and run into issues that are only showing up in IE browsers, do you bill the client for the extra time it takes to try to figure out how to make the site work on that crappy browser? I know the web developer(s) we used for the farm calculator [a project for which he was the client] bill for everything, even if they are redoing something they screwed up… but I’m curious as to your way of handling things like this. I want to be fair to my client, and myself!

This is a great question, and goes beyond just “IE browser” issues.  Here was my answer:

When I run into an IE problem, I will usually stop and ask the client if making it work perfectly on IE is really important to them.  It would be useful to have stats for IE on their website (or the broader internet: http://en.wikipedia.org/wiki/Usage_share_of_web_browsers ), so they can know if 10% of their users are on IE6 or 0.01%.  It also would be useful to have an estimate for how long it will take (as long as you’re clear that it is an estimate).

If I’m billing time and materials, and I’ve had this conversation, I absolutely bill the client, but try to keep them informed as to how long this is taking me.

If it is a fixed bid, then I might go to the client and say ‘I’ve run into this issue, for this browser, which is x% of your website traffic.  There’s solution A and solution B, but both of them are things I didn’t expect.  Can we talk about this additional work’.  If they say no, I grit my teeth and deal.

So, to make it more broadly applicable, if you run into issues that you didn’t expect, here’s my advice:

  • Stop work and identify the issue.  Don’t keep spinning your wheels.
  • Gather useful facts to help the client make an informed decision (IE browser % in the example above).  Include a rough estimate if you can, but make sure the client knows it is an estimate.
  • Talk to the client about the issue and find some kind of resolution.
  • If the resolution is you doing the work, then, if you are on a fixed bid, explain how you didn’t consider this particular issue and see if the client is flexible about paying for it.
  • If the resolution is you doing the work, and you are on a time and materials contract, then bill for the extra work.
  • In either case make sure you keep the client in the loop about time spent and schedule changes due to the issue.

Surprises come up all the time.  What is important is that you come to a fair accommodation with your client.


GWT Code Splitting Process Tips

I have written before about GWT code splitting, a cool feature available in GWT.  While I am definitely no expert, it seems to be different that options offered by other, comparable web toolkits.  Just doing a quick survey (thanks, Ajaxian!), there seems to be a lot of code compilation happening.  Some of it is at deployment, pruning unused library code (like here, and here).  Some of it is aimed at making whatever javascript you write, better (like this and this).  There’s even tools aiming to document (in json) all javascript features supported by browsers, so that you can intelligently target user agents.

GWT code splitting is different from all of that.  It is developer determined split points in javascript code.  A developer says, essentially, all code after ‘this call’ should be downloaded and made accessible to the runtime when ‘this call’ is made.  More at the canonical reference; you should read this multiple times if you want to really understand code splitting.

As the document above mentions, “effective code splitting requires iteration”.  I’ve spent a fair bit of time in the last week doing some code splitting, and wanted to share my punch list (and build on my previous code splitting post).

First, understand the three major types of chunks your code will be split into.

  • Initial download
  • Leftover code
  • Exclusive fragments

The document above has a great diagram, which also includes other types of code which I have not run into.   The important thing to realize is that minimizing the initial download is important, but if any of the exclusive fragments are download, the leftover fragment will be downloaded.  Therefore, a better goal is to maximize the exclusive fragment size.

Here are places places to put split points, in order of preference

  • subsystems easily isolated (encryption library, etc).  Consider using the AsyncProxy, which is a great way to hide a subsystem
  • user actions (onclick events, etc).  Be aware of latency when toe code is downloaded and executed
  • when enabling spans are present

Use GWT.runAsync directly.  I tried to get all fancy with commands and abstracting it away, and didn’t have much success.  You can surround it with a timer, though, and that
may make sense when you are using an enabling span.

if (span is present) {
Timer t = new Timer() {

@Override
public void run() {
GWT.runAsync(new RunAsyncCallback() {
public void onFailure(Throwable caught) {
// handle error
}

public void onSuccess() {
foo();
}
});
}
};
t.schedule(150); // wait 150 ms before trying to download this code
}

You will spend a lot of time compiling, so only target a few browsers for compilation.  When I added the -compileReport option, the compile time for the main module went from 2 minutes to 8 minutes.  However, once you have the url for the compile report (something like /extras/modulename/soycReport/compile-report/SoycDashboard-0-index.html) you can actually see the results about a minute in.  At that point, you can stop the compile process.

Method call hunting will make you love your IDE java method search (control-H in eclipse–here’s a useful cheat sheet)

Watch out for constants and static methods.  In fact, I end up pulling out my constants to a class shared between GWT and my java server so that I can name spans like this
<div id="<%=Constants.SCROLL_ANCHOR_ID%>"></div> and be assured that GWT components will always be able to attach to those spans.

If module A is called by module B, C and D, avoid putting the GWT.runAsync calls in modules B, C and D.  This would force module A into the leftover code chunk, increases the number of split points, compilation time, and memory needs.  Instead, put the GWT.runAsync calls into module A, which pushes all that code into an exclusive chunk.  If you have a bunch of small splits points in your compile report, look at it carefully, especially if they are in the same class and see if you can push the split points back into the common code.

Code splitting failures (onFailure) should be dealt with the same way any remote access failure is dealt with in your application.  I haven’t found a more intelligent method than informing the user that the operation failed, however.

Set goals for splitting and try to avoid getting sucked in.  Because it is an iterative process, you can end up spending a lot of time with this.  Sometimes changes can have counter intuitive side effects, so make sure you track both total, initial and leftover code chunk sizes.

This post was based on a system with total obfuscated code size of approx 750kb, compiled using GWT 2.1.1.


Code splitting in cross domain GWT components

I just upgraded to GWT 2.1.  Lots of new features, though they are mostly aimed at building webapps (as opposed to enhancing websites).

The upgrade process was pretty painless.  A couple of notable changes (for my app):

  • <code>DeferredCommand</code> has been deprecated, and replaced with <code>Scheduler.get().scheduleDeferred</code>.  However, the API didn’t really change all that much, so this update is a simple search and replace (looks like the documentation has not yet been updated).
  • <code>HTTPRequest.getAsync</code>, which has been deprecated for years, finally disappeared.

The big win for me was code splitting when using the cross site (xs) linker.  This means that code served from one host can run on other domains and can include code splitting in the same manner as code that runs on the original host.

Why is this a big deal?  Two of our key widgets run on both our main host and subsidiary hosts.  These widgets are relatively complex, and it would be great for performance to split out that code so it wouldn’t be loaded on pages where it wasn’t shown.  This wasn’t really possible before GWT 2.1.  I’m still in the process of putting in the code split calls, but will let you know what the savings are when I’m done.

Update Jan 8, 2011: I was able to cut about 18% off the initial and leftover code download size.


What did I ship in 2010?

In the spirit of this post, I wanted to outline what I shipped this year.  (Shipped in the sense of software–building something and putting it out to the world.  Personal achievements in the past year, not least of which was getting married to my lovely wife, aren’t in the scope of this list.)

  • 41 blog posts on this blog, and 95 posts on two others I run.
  • Many, many releases (over 20) of COhomefinder.com.
  • Released version 2.0 of a dating site for the mentally ill.
  • Rewrote my Colorado CSAs directory and vastly increased the number of CSAs contained.
  • With a team, researched and presented a plan for a local Boulder currency.
  • Scoped, built (with a team), and launched an ecommerce website.
  • Set up a scholarship for a permaculture course.

As Seth said about his list, there were other projects I didn’t have the guts or follow through to launch, but I’m pretty happy with this list.  Here’s to 2011!



© Moore Consulting, 2003-2017 +