Saturday, April 26, 2008

Moving this blog

This is my last post using Blogger. I have moved my blog to TypePad to give it new life and a new focus.

GO TO MY NEW BLOG

Friday, April 25, 2008

New Focus

When I started this blog, I gave it the subtitle of "Exploring the technical, sociological and economical foundry blocks of the World Wide Web.". I found that most of my post hovered around the technological concepts of RIA and the web as a platform. Probably because I was working mostly as a software engineer at the time. As I have been shifting more to the user experience, interaction design and product management, the more I became dissatisfied in the details of the technology. I have not only the sociological issues more compelling, but the psychological and particularly cognitive issues of web as a platform more and more important to where the web is going, and what is in it's future.

So, I am shifting this blog to "Exploring the psychological, economical and technical structure of the Internet." I am preparing a flurry of blogs, and plan to start posting much more readily in the very near future. I may end up moving this blog, and if so, my next post may be my last on blogger.

Tuesday, April 1, 2008

Why CSS's CLIP is your friend

When you get to the point on a project where page load-time becomes a concern, there is a usual play book that most of us pull out.


  1. Glob your CSS and JavaScript into as few files as possible.

  2. Pack or minify your JavaScript.

  3. Trim whitespace in your CSS.

  4. Start pre-loading images for roll-over effects.



Maybe you go so far as to lazy-load content via JavaScript. However, I will still do you one better...

Glob your static images onto one image map. Place all of your icons, or all of your tabs and their rollover counterparts into one larger image. Then, in the css of each image element, add a Clip definition to the CSS or style attribute.

What are the benefits?

In this case, the whole is less than the parts. This means smaller file size, but more importantly, it means far less packets. Each file is at least three packets on the wire. So, with lots of small files, such as a dozen or so icons, you can reduce the number of packets on the line by as much as two-thirds.

The second nicety of using clip is that mouse-overs are really smooth when you just shift the clip's rect rather than swapping out images.

There is another cool side-effect. If your site is slow loading for any reason, (i.e. client's machine is bogged) images will load in neat batches, rather than trickling in. This tends to actually make your site seem like it is less broken. Many users are more often annoyed by that one image that has not loaded, than when the whole lot is still loading. It is just distracting. Pay attention next time, I bet you will agree.

What are the pitfalls?

There are only two. First, clip: rect(); can be a pain to specify. You almost never get the math right the first time. (x,y,w,h) would have been a far better specification. Second, you need to pay close attention to what images you group together. Do not group together an image that should be jpeg with an image that should be a gif, and when grouping gifs, pay very close attention to the color pallet and make sure you are grouping like-images and not sacrificing too much picture quality.

That said, this trick is one that really should make into a lot of developers performance play books.

Wednesday, March 19, 2008

Opening up to OpenSocial, OpenID, hCard and oAuth

So, there is a flood of propaganda coming out of the web 2.0 conferences either about OpenSocial, OpenID, oAuth or hCard. And many people seem to be smoking the peace pipe and passing it along. Sorry, but I don't smoke, and I don't read the tabloids. Usually, I like to wait until a technology is bound and in print, before I am ready to commit. Sorry, but it is an old guy's habit after seeing too many idealogical fads hit the Internet.

However, a co-worker said something today that actually made sense to me. And it was not about only having one login to remember, or how cool it was to link all your accounts together, or any other feature set that has been tried before. It was the way he related the registration process to a check out process, and indirectly related the registration information to credit card information.

...Okay, so you probably do not get why this excited me enough to write a blog about it, but read on...

For the last few weeks I have been doing a lot of reading on usability, design, and marketing. And the only thing that I think every time someone mentions these technologies is "So great. You want me to both convince users to register with my site, and do so using a process they are unfamiliar with?" What if my user does not have a GMail or Blogger account? How are you not setting me up to just confuse a lot of people? I mean, how do you expect to sell this to non-geeks? The n00bs? My mom? (Yes, my mom is my favorite test-case for usability. If she gets it, everyone does.)

So, the concept of these services as personal information brokers in the same way that Visa and Mastercard are brokers of my credit card information is powerful. If registration is a checkout, your login is your credit card information, and sign-in is like Amazon's 1-click purchase. This ability to relate these systems to a very well established user interaction might just give this whole thing some credit. I can now see a small sliver of light that suggests this stuff might make it to hard copy, might be around in three years, and might be worth my time considering.

To the many behind OpenSocial, OpenID, hCard, oAuth, and whatever else is out there, my suggestion is this: Stop selling this stuff to me, the web 2.0 geek, and start figuring out how you are going to sell it to my mom. You do that, and you will have a recipe for success. So, please go fire up your branding iron and get to work, because you have long chasm to cross if you really want this to catch on.

Saturday, March 8, 2008

GUIDs, UUIDs, and Canonical Names in JavaScript

Creating unique identifiers outside of a database tends to be a bit of a pain. So, why would you do it? What if you were not using a database? What if you have distributed servers? What if you want clients to be able create distinguishable content without constantly contacting the server? For example, if clients are aggressively creating parallel content, then it would be advantageous for you to be able to lazily sync the content without causing significant lag and interruption to the user. I realize that most of you will not run into this, but for those of you who do, here are some helpful notes:

Firstly, I can't tell you how many postings I found that led to tutorials using an ActiveX object to create a UUID. If you have only IE-using clients that do not have stringent security settings, then I guess you can use this. Otherwise, it is no good.

I soon found This UUID library from AF-Design, which is alright, but there are obvious inefficiencies, such as the way it computes time in milliseconds out the long way instead of just using Date.getTime(). Also, a serious design flaw is that it doesn't use any unique data other than time in milliseconds to generate the UUID. To be a true UUID, it would need to utilize unique data to the machine such as IP, or even better the MAC address. Otherwise two machines could potentially generate the same UUID.

Understandably, there is no method for fetching the mac or ip address using only JavaScript within a browser. But, you can make the client's IP available to the JavaScript running on the client browser by echo-ing back the REMOTE_ADDR from a request header back to the client. For an example of how to do this in PHP, see http://unix.cms.gre.ac.uk/code/php/examples/remote_addr.php.

Since I usually do not care to have my unique id's in the traditional UUID format, I tend to go with a canonical name using an MD5 hash of the time and IP. The result is more reliable than the UUID example above, and is actually a bit faster and easy to implement:


function cn() {
var t = (new Date()).getTime();
var ip = '192.168.1.100';
return MD5(t+ip);
}


I hope this helps any of you dealing with a similar design problem.

Monday, January 28, 2008

Zero-width whitespace and what it can do for you...

One of the most common layout problems I see in the web 2.0 space is accounting for the odd shaped content some people post. Long URLs are among the most common nuisance. Take for example:

http://www.google.com/search?hl=en&client=firefox-a&rls=org.mozilla%3Aen-US%3Aofficial&hs=G12&q=zwsp+zero-width+space&btnG=Search

A long URL like this often overflows its container and is a layout nightmare. Most people's response is to simply set an overflow value, and either hide the remainder, or have a horizontal scrollbar. Neither of these solutions are ideal. Either way you are obscuring content, and I think everyone agrees that, in a web layout, horizontal scrollbars are the devil.

The solution to this problem is Unicode character U+200C. (a.k.a. ​ or &zwsp;) This character achieves the exact opposite of the common non-breaking space ( ). Zero-width space does not render a visible space to the screen, but acts like a space for breaking up text when wrapping. Here is a javascript example of how to use it:


function linkify(text) {
var pre = text.substr(0,text.indexOf("http://"));
var rest = text.substr(text.indexOf("http://"));
var url = rest.split(/\s/,2)[0];
rest = rest.split(/\s/,2)[1];
var link = '<a href="'+url+'">';
link += url.replace(/(\/|\+|=|\-)/g,"$1&#8203;");
return pre+link+'</a>'+((rest)?rest:'');
}


For the URL above, this would render the following html:

http:/​/​www.google.com/​search?hl=​en&client=​firefox-​a&rls=​org.mozilla%3Aen-​US%3Aofficial&hs=​G12&q=​zwsp+​zero-​width+​space&btnG=​Search

Now this link nicely wraps to fit inside its container, and one of your worst layout nightmares is easily solved. I don't think it takes much creativity to figure out the other potential applications for this character.

I cannot tell you what a pain it was to make sure every &, <, and > symbol in this post was properly escaped, so I hope you found this helpful.