NOTE: This blog has been moved to http://www.looksgoodworkswell.com

Showing posts with label development. Show all posts
Showing posts with label development. Show all posts

Saturday, October 03, 2009

Silicon Valley Code Camp Talk - DHTML Prototyping

For those at the Silicon Valley Code Camp (and anyone else :-) here is the talk from today. I added references that I mentioned to the end of the slides. Also I mentioned CSS Specificity via Star Wars. This is a great way to learn the rules for CSS Specificity. You can also download the PDF for a larger version here.

Thursday, May 21, 2009

WebVisions 2009 - Bringing Design to Life

What are the disconnects between web design & web development? How can the two work together more efficiently? What do developers wish designers knew?

I gave this talk today (May 21, 2009) at WebVisions 2009. Enjoy!

Thursday, February 12, 2009

Interview: What Developers Wish Designers Understood

Lou Rosenfeld interviewed me on the topic "Bringing Design to Life: What Every Designer Should Know About Interface Engineering". This is a really interesting subject and gets to the heart of how to get engineering and design teams to work together better.

The interview gives you some of the points I will cover in my upcoming webinar on the same topic (Feb. 26th, 10AM PST/1PM EST).

Also there is a short video presentation (about 7 minutes) that provides a sneak peek into the webinar presentation.

Use code RMWBNR for a 20% discount off your ticket purchase.

Thursday, January 15, 2009

Upcoming Talk: Bringing Design to Life (Rosenfeld Future Practices Webinar) - Feb 26th

Auroville: Under Construction (by premasagar)I am excited about a new online seminar that I will be giving Bringing Design to Life: What Every Designer Should Know about Interface Engineering. This is part of the Rosenfeld Future Practice Webinars series (a joint venture of Smart Experience and Rosenfeld Media).

For the last 25 years I have been solidly focused in the world of user interface creation. At times I have been solely focused on design and at other times on interface engineering. At other times I have held both responsibilities at once (e.g., leading a UX team while leading two interface engineering teams). Having spanned both design & engineering, I deeply understand the challenges is translating ideas into products. For this talk I decided to focus specifically on how web designers can work in the most efficient manner with their engineering counterparts. It is the "stuff" that most engineers wish their design colleagues knew.

This 60-minute webinar is initially available as a live class, and then is made available in a DRM-free recorded, edited format. By avoiding the travel required in attending a physical seminar or conference, you save money and reduce your impact on the environment. You are free to watch the webinar with colleagues in a conference room, making for an even better value. The cost is only $129.

Join me on Feb. 26th (18:00 GMT / 1pm EST / 10am PST) for Bringing Design to Life: What Every Designer Should Know about Interface Engineering.

(Previous webinars include Luke Wroblewski on Modern Web Form Design and Indi Young on Using Mental Models for Tactics and Strategy. Also check their schedule for a complete lineup of monthly webinars.)

Also, if your are interested in purchasing materials from Rosenfeld Media, please use my discount code when you visit the site (good for a 15% discount): SCOTTWBNR.

Photo credit: Auroville: Under Construction from premasagar's flickr stream, Creative Commons License.

Tuesday, October 14, 2008

YUI Carousel Component (2.6.0)

On October 1, 2008 Yahoo! announced the release of YUI 2.6.0. This
release contained the official YUI Carousel component.

As you know, the intent of my carousel component was to fill in a gap in the YUI library. In 2006, I created the ycarousel component. Thankfully, many people have found it useful over the last 2 years.

Before I left Yahoo! in 2007, I spent some time with the YUI team,
discussed the ideas behind the way I approached my component, what I
liked about it and more importantly what I did not like about it :-)

The newly released YUI component shares some of the same
properties/api with my component but has been written from the ground
up. So I am excited about their
new carousel and encourage everyone to migrate to it instead of using
the carousel shown at this site.

The fact is you will get better support for their component. I am just
too busy with other projects to really support it the way I would like
and there is just no reason to cloud the space with two components
(even named similarly ;-)

You can find the new YUI Carousel component at the YUI library site.

The latest version of my carousel can be found at my site.

Wednesday, October 01, 2008

Netflix Public API Available

I am proud to say that Netflix has just released its public APIs.

The API allows access to data for the catalog of 100,000 movie and TV episode titles. This includes DVD titles as as well as instant watch titles. Applications can request access to a member's account (via OAuth) for working with their queue as well as other movie related account information.

Best of all it's free. We allow commercial use (e.g., a developer can create an iPhone app and sell it for a buck -- that's ok).

I gave a lightning talk about this at the Ajax Experience yesterday in Boston. It both quickly covers the API as well as our first Netflix Hack Day where we exercised the APIs in a 24 hour coding frenzy. I will upload this to slideshare when I get a decent internet connection (why can't these new beautiful hotels have decent internet connectivity?)


Developers can get access by signing up at http://developer.netflix.com.

BTW, there is also a great step-by-step tutorial from Joseph Smarr (he is the platform architect for Plaxo)

Happy Hacking!

Sunday, June 22, 2008

Friday, June 20, 2008

Announcing: Jiffy Firebug Extension for Viewing Client Side Performance Data

In the previous article I discussed our full cycle tracing mechanism we built at Netflix.

Firebug Extension: First Attempt
When I was trying to explain the capabilities of this system to others in the organization, I started doodling in Apple Keynote to see if I could create a single diagram that captured all of the timings and what was really happening during a full cycle trace. This is where the diagram I used in the previous article came from. Here is the diagram:

roundtrip-blog-capture-alltimes.png (by billwscott)

This got me thinking. What if I could create a tool that would take the timings from the web page and render it with real time data. The obvious solution was to build this as a Firebug extension. Here is what the tool ended up looking like once it was plugged into Firebug:

roundtrip-firebug.png (by billwscott)

The nice thing about this visualization is that it clearly puts the timings in context. You can see the Response overlapping with the Page rendering (which is a good thing). You get a clear picture of how the measurements fit together.

Currently, this is not available outside of Netflix. There is some code cleanup, upgrade to FF3/Firebug 1.2 needed as well as it is tied to the type of metrics I described previously. If others think it is useful I will try to burn some cycles, make the data source more generic and get it out for public use.

Jiffy Firebug Extension

However, I was showing this to Steve Souders (in relation to the Velocity panel) and he mentioned that one of the other panel members, Scott Ruthfield of Whitepages.com and his team were building an open source metrics and instrumentation tool for Web pages called Jiffy.

In the words of Scott:
Thus we built Jiffy—an end-to-end system for instrumenting your web pages, capturing client-side timings for any event that you determine, and storing and reporting on those timings. You run Jiffy yourself, so you aren’t dependent on the performance characteristics, inflexibility, or costs of third-party hosted services.
Steve suggested adapting what I had done with the current Neflix Firebug extension for use with Jiffy.

I quickly realized that since the focus of Jiffy was for measuring on the client page (as well as a way to log measurements) that I needed a more generic way to view the data. I decided to model this new measurement panel slightly after the Firebug Net panel.

The result is the Jiffy Firebug Extension.

Jiffy Firebug Extension

Today I am making this extension available to the public under a simple Creative Commons License. Simply put, this adds a new panel to firebug that provides a nice way to view timing measures either in a collapsed or timeline view. It's also flexible. You can wire it to other libraries besides Jiffy if so desired.

You can learn all about the extension and read more about the Jiffy library at my Jiffy Extension site or go directly to the Jiffy-Web google group.

Blogged with the Flock Browser

Measuring User Experience Performance

One of the projects my team at Netflix is busy with is improving the end-user performance experience. Anyone that reads my blog regularly knows that I am a champion for great user experiences. Often the performance angle is not included in discussions of the user experience. But as we all know the best design can be crippled by sluggish execution, waiting a long time for a page to be fully interactive or feedback that does not come in a timely manner.

Timing "from Click to Done" - Full Cycle Experience

User performance experience focuses on what is the full cycle time from when the user requests a page or invokes an action till a new page is ready for interaction or the action has completed. Most sites have various ways of tracing parts of the performance puzzle. Often backend instrumentation is inserted to time backend services. But a lot of sites don't have a complete picture of just how much time is the user spending from the time they click it till the time they get it back (done).

To address this issue at Netflix, one of the first things I initiated after joining Netflix was the creation of full cycle tracers. Kim Trott (on my team) took the idea, ran with it, fleshed it out and turned it into reality.

The idea of tracing the full cycle time is to:
  • Capture the start time
  • Capture various points of interest
  • Capture the end time
  • Log the results

Capture the Start Time ("from Click")
To get a full cycle time we need to capture the point in time the user makes a request.

At Neflix we use the following stack of technologies: Java, JSP, Struts2, Tiles2, HTML, CSS and Javascript. Within the normal HTTP request/response cycle our requests are handled via Java servlets (eventually routing through to JSP for Web pages).

roundtrip-blog-capture-starttime.png (by billwscott)

Unload Event
The most logical place to measure the start of a request ("from Click") is on the originating page (see A in figure above). The straighforward approach is to add a timing capture to the unload event (or onbeforeunload). More than one technique exist for persisting this measurement, but the most common way is to write the timing information (like URL, user agent, start time, etc.) to a cookie.

However, there is a downside to this methodology. If the user navigates to your home page from elsewhere (e.g., from a google search), then there will be no "start time" captured since the unload event never happened on your site. So we need a more consistent "start time".

Start of Servlet Response
We address this by providing an alternate start time. We instrument a time capture at the very earliest point in the servlet that handles the request at the beginning of the response (see B in figure above). This guarantees that we will always have a start time. While it does miss the time it takes to handle the request, it ends up capturing the important part of the round trip time -- from response generation outward.

There are a number of ways to save this information so that it can be passed along through the response cycle to finally be logged. You can write out a server-side cookie. You can generate JSON objects that get embedded in the page. You could even pass along parameters in the URL (though this would not be desirable for a number of reasons). The point is you will need a way to persist the data until it gets out to the generated page for logging.

Note that the absolute time captured here is in server clock time and not client clock time. There is no guarantee these values will be in sync. We will discuss how we handle this later.

Capture Intereresting Points Along the Way
After capturing the start point there are a few other standard points of time we would like to capture.

roundtrip-blog-capture-tweentimes.png (by billwscott)

Two points of interest are captured on the servlet side:
  • When we begin generating the HTML for the page (C)
  • When we end generating the HTML for the page (E)
Two points of interest are captured on the client side:
  • When start rendering the HTML for the page (D)
  • When we end processing the HTML for the page (F)
C & E deal with page generation. D & F deal with page rendering.

In D, we emit a scriptlet immediately after emitting the <HEAD> tag that saves new Date()).getTime() into a Javascript object on the page.

In F, we emit a scriplet immediately after emitting the </BODY> tag that saves new Date()).getTime() into a Javascript object on the page.

When the page starts rendering the HEAD it will execute D and store the time stamp. When the BODY finishes rendering, it will execute F and store the time stamp.

Capture End Time ("to Done")
Once F is finished however, this does mean that the page is completely rendered. In parallel, the browser has been loading CSS, Javascript, requesting images and rendering the page. But the page is not ready for the user to interact with (typically) until the onload event is finished for the page (see G in diagram below).

roundtrip-blog-capture-endtime.png (by billwscott)

We attempt to insert our instrumentation as the very last item to be handled in the onload event for the page.

Logging the Captured Times
Here is a diagram that shows the various time points we capture (8) and the measures we derive (5).

roundtrip-blog-capture-alltimes.png (by billwscott)

The five measurements are:
  • Elapsed client request time (G-A). Full cycle time. The total time it took to request the page, receive the response and render the page. Not available if the referring page is not a Netflix page. This is not available for all measurements.
  • Elapsed server response (E-B). How much time was spent generating the server response.
  • Elapsed client render (G-D). How much time it took the client to render the page (and get the server response). Since we stream our response to the client, there's no way to differentiate how much of the client rendering time was spent getting the response from the server vs. rendering the page. The browser will start to render the page as it receives the content from the server.
  • Elapsed server plus client (C-B) + (G-D). Total time to render; full time to generate the response and render it client-side. This is the key measure we use as it includes the most reliable start time (that we can capture all the time). It is the summation of the client render time (G-D) and the elapsed server response (C-B). By taking the deltas on the client and the server separately we can safely add their values together to get a total time (even though they are captured in different server clock times). The caveat is there can be some gap between the time C emits the HEAD tag and the corresponding Javascript time stamp and the time D starts rendering. In practice we have found this time to be sufficiently small on the whole so have kept to this simple approach.
  • Elapsed  client render after body (G-F). This gives us an idea of how much additional time is needed to get the page fully loaded after rendering the body.
At this point we can gather up the five values (persisted so far via server-side and client-side cookies or some other methodology) and write these out to a server log. This could be done via an Ajax call, using beacons, an HTTP request with a NO-CONTENT response or some other mechanism. The back end service caches up results and writes them to a database for later analysis.

The Benefit of Measuring
We could have chosen to implement all the yslow performance suggestions without measuring anything. Most likely they would all be wins for us. But by putting a full user experience performance tracing mechanism in place we can be confident that enhancements, features, or even attempts at performance improvement did not negatively affect site performance.

Recently we fielded a different variation of our star ratings widget. While it cut the number of HTTP requests in half for large Queue pages (a good thing) it actually degraded performance. Having real time performance data let us narrow down on the culprit. This feedback loops is an excellent learning tool for performance. With our significant customer base, large number of daily page hits we can get a really reliable read on the performance our users are experiencing. As a side note, the median is the best way to summarize our measurements as it nicely takes care of the outliers (think of the widely varying bandwidths, different browser performance profiles that can all affect measurements.)

In future articles
  • Discuss what has worked and not worked.
  • Discuss an internal firebug extension I wrote to visualize this data for our developers.
  • Compare Safari vs Firefox vs IE -- the results are really interesting.
  • Announce a new Firebug Extension that helps visualize performance page data.
Hear More About this at the Velocity Conference
As I mentioned in my previous article I will be giving a 15 minute talk on Improving Netflix Performance at the Velocity Conference. I will cover some of this material as well as other information in that talk.

Credit
Thanks to my excellent UI Engineering team at Netflix, in particular the hard work of Kim Trott. Thanks also to the yslow team for giving us some concrete ideas on improving site performance.
Blogged with the Flock Browser

Thursday, May 15, 2008

Everything Good You Needed to Know About Javascript*

(*and even the bad parts)

At Yahoo! I had the privilege of working directly with Doug Crockford and got to review a book he was writing at the time, Javascript The Good Parts.

This book is different than most other Javascript books. It just focuses on the language itself and not the browser DOM. It reveals both gems and warts. And it does it in a simple straightforward manner. It reminds me of the classic The C Programming Language book that I cut my teeth on.

This is a must for your bookshelf.


You can get JavaScript: The Good Parts at Amazon.

Thursday, October 04, 2007

MIMA - Jason Freid

Finally got to hear Jason Fried (37 Signals) in person.

I know that Jason is controversial and his stance on team size, ways of working are controversial and cannot (I believe) be applied in every situation.

Its a lot like Extreme Programming. Back at Sabre I lead two engineering teams and we were doing full on XP, agile methodology. As long as it was not treated like a religion but was a set of principles to inform your work I found it to be really useful.

Onto the talk. Jason had some great points. Lots of things that I agree with.

Keep your team small
  • Forces you to focus on what's important
  • Clearer communication comes for free
  • "Communication usually fails except by accident"
Collaboration is about communication, not control
  • Keep your team apart. Interruption is not collaboration. Interruption is the enemy of productivity.
  • Encourage alone time
  • Stay away from each other as much as possible
  • Communicate more passively, less actively.
Meetings are toxic
  • Usually a symptom of a problem, not a solution. Mentioned a business leader in Brazil who advocates that all meetings are optional.
  • Meetings convey an abysmally small amount of information per minute
  • Require thorough preparation that people rarely do
  • Tend to procreate
Instead make tiny decisions
  • Decisions are progress
  • Progress is great for morale
So I am a realist. Organizations do grow in size. So you have to work hard at keeping teams small. And we should avoid meetings wherever possible. However (and Jason talks about this) you need to communicate with each other in ways that are least disruptive. Meetings do have to happen (Jason is not saying never have a meeting... just they are very infrequent and really are more working sessions).

In different teams I have led I have instituted things like "No Meeting Days". No one is allowed to call a meeting on those days. Or "Work from Home Days". They were all designed to give designers & engineers "flow time". Time to get into the flow of what they are doing and stay there.

If you can have a few hours of non-interrupted productivity it is amazing what you can accomplish. I have had people remark at my crazy "weekend projects". What happens is I get off by myself, no interruptions, no IM, no email and just get into the flow of what I am working on. That zone is the same thing a runner feels with they get that "glow", the groove of running.

Jason talked about the power of REM sleep and compared it to REM Work. Uninterrupted flow. What is interesting is I have over the last few years biased toward open office arrangements. I am beginning to rethink this. Why? Its too easy to interrupt your co-workers with trivial stuff that doesn't demand immediate attention. And verbal communication can be very redundant and time consuming.

A couple of months back I was trying to get a lot of stuff done. So instead of checking email every 15 minutes (!) I decided to check once in the morning and once in the afternoon. Man, I cannot tell you how it changed my day. The ability to get into some work without interruption was exhilarating.

If nothing else, Jason's talk was a wonderful reset for me to think how I manage and remember my number one priority is to make those that work for me successful, productive, motivated and appreciated.

Saturday, September 08, 2007

Why Protoscript?

Ok, the last thing in my mind when I created Protoscript was for it to be YAT (yet another toolkit).

I have been asked several times what really makes this different than toolkits like jQuery. And what is the compelling reason that someone would use Protoscript.

The motivation is straightforward:
  • Prototyping is too hard for non-techies
The reasons Protoscript can help solve some of the difficulties with prototyping are as follows:
  • Simplifying how we express interactions is a good thing
  • Behavior injection is a powerful iterative design tool
  • Plug-in Behaviors guarantee a growing set of prototyping solutions
  • By focusing on prototyping, things get simpler
Prototyping is Too Hard for Non-Techies
The end goal of Protoscript is a simple GUI that will allow non-techies to:
  • Go to any web page
  • Sprinkle simple to complex interactions onto that page
  • Do all this without writing code, but simply through an intuitive interface
I am a huge proponent of breaking down the barriers for the non-techies among us to be able to do what us techie geeks can do.

I have been fortunate to work with some awesome talent, many of which do not have the skills, the time or patience to prototype in Javascript.

Do I want to exclude them from the party? No.

If I can let more team members literally play with a working site and tease out better interactions then I have raised the state of the art (even if ever so slightly).

Simplifying how we express interactions is a good thing
By allowing an interaction to be expressed in a consistent, stylized declarative fashion (JSON) a whole set of goodness becomes available:
  • Widely variant interactions captured with same simple syntax
  • Nested syntax communicates the relationship between behaviors, events, callbacks & attributes
  • Non-programmers can read Protoscript better than JavaScript code. jQuery comes the closest to making Javascript readable by non-programmers (see discussion below on Protoscript and jQuery).
  • It is a lot easier to write a GUI tool that reads and writes JSON than it is to read/write Javascript. (This is why so many tools use XML or JSON since they are declarative formats)
  • JSON can be sent over the wire. This means a simple REST service could serve up and/or save JSON to remote services.
  • JSON is easier to parse
  • JSON is easy to write out to a database or as a flat file
Behavior Injection is a Powerful Iterative Design Tool
The Protoscripter bookmarklet is the first step in providing behavior injection. It allows you to popup the bookmarklet on any web page and type or paste in Protoscript code to inject interactions. (You can get it from the Protoscript Home page.)

Here is a fun example of this... Watch as I experiment with burritophile.org (mind you this is a contrived example)



Beyond the bookmarklet, it should be straightforward to create a Greasemonkey script that loads Protoscript (Alex Russell's suggestion) or a Firebug extension that adds prototyping to Firebug (Steve Souders led the way with YSlow) or a full on Firefox extension that brings palettes of behaviors to a page and adds smart element selection to make behavior injection simple.

And of course the extensions also open the door for being able to save the configuration to your desktop and recall/edit as needed.

Plug-in Behaviors guarantee a growing set of prototyping solutions.
Non-partisan, extensible plug in architecture allow an ever-growing set of interactions. Out of the box I support YUI as the behavior set (behaviors, events, callbacks and attributes) and jQuery as the selector mechanism (supports CSS selector syntax and XPath). But Protoscript allows you to add any number of new behaviors, write your own behavior set on other Javascript toolkits and plug in a different selector query mechanism.

This means that Protoscript is really not in opposition to tools like jQuery. I really like jQuery. I have always been a fan of syntactical sugar. It lessons the cognitive load when writing code.

jQuery has a powerful chaining and filtering mechanism that allows you to control the scope of elements you are applying behavior to.

Some of the advantages of Protoscript over jQuery for prototyping are:
  • In jQuery, behaviors are passed parameters and since they can vary in the number of parameters that get passed to them it is not easy to parse, stylize of guess at what must be passed. Protoscript promotes the parameters to be attributes in the JSON thus making the syntax the same across all behavior plugins. Since they are attributes they can also be read by external gui tools to automatically create a GUI interface
  • Protoscript uses a nested syntax instead of a single line of chained code. This allows protoscript to express chained behavior, changing scope and attaching behaviors & events (both can be done easily in jQuery). Where the JSON syntax gives a novel twist is now you can express in one interaction set a number of serial as well as chained actions.
  • Event expression is richer in JSON since you can express multiple events in serial fashion along with multiple callbacks thus capturing the forking nature of interaction as a tree instead of a single list.
Now I hasten to add that I do not believe Protoscript in anyway replaces jQuery. That in my mind is wrong and missing the point. Heck, I wrap jQuery and use it for my query selection (but not for behaviors, callbacks, etc. in the YUI reference implementation). jQuery does more in raw power than Protoscript ever aims to do.

Quite simply I am focused on prototyping. jQuery certainly can be used for prototyping. I just think that for all the reasons above it made sense for me to take a different approach.

By focusing on prototyping things got simpler
Protoscript just says, hey what if we did not try to everything that you need to do write a full-blown application... but instead focused on what you need to do to prototype.

When I looked at it that way it simplified the building blocks and the way you might hook them together.

The design of the JSON syntax was actually driven by the way I imagined the prototyping GUI tool would look like. That is certainly a different approach than most toolkits take. And the only reason I could take that approach was because of the laser focus on prototyping.

one possible concept of protoscript gui

Doesn't this make sense?
Look, I have created this and plan on continuing to grow and expand its capabilities. I have no aspirations to replace what anyone else is doing. I have struggled with this problem for over 25 years and especially the few years trying to bring richness to the web.

I have tried to make this as non-partisan as possible.

Hopefully others will create behaviors around their favorite toolkits (or adapters to their behavior sets) so that the GUI tools built for this will be able to seamlessly use them as well.








Thursday, September 06, 2007

Announcing Protoscript



Wow. It has actually been 2 months since my last post. Nope. I have not fallen off the planet. This has been one of the craziest times I have experienced in a long time so while I have had a lot to chat about I have not had the time to blog coherently.

One of the projects I have been working on is a way to make it easier for all of the non-techies (as well as techies) to be able to experiment with various interactions on a web page in lightweight manner.

By lightweight, I mean to say a way to take an existing web page or a prototype of a web page and "sprinkle" rich behaviors to play with concepts. Ideally you should be able to express an interaction in a declarative manner without having to write JavaScript directly (but not kept from it if you need to). And even more ideally you should be able to build up the "legos" of interaction in simple GUI tool embedded in the browser so that you are not encumbered with even a simple syntax to type in.

So back in July, I was slated to give a talk at the Ajax Experience. I promised a few months before that I would have 2 new talks. One on Anti-Patterns (yes I owe several blog posts on that one) and the other on prototyping.

The problem was exactly one week before both talks I had literally had not time to put those talks together. So I dropped out for a few days to create a very early version of what is now protoscript. The good news was that it was actually fully functioning and I gave a peek of it at the conference.

I got a lot of good feedback from the talk and went back and rewrote it a couple of times, changed up some of my approach, moved to a plug-in style architecture, etc.

So, ok, what is protoscript?



Protoscript is a simplified scripting language for creating Ajax style prototypes for the Web. With Protoscript it's easy to bring interface elements to life. Simply connect them to behaviors and events to create complex interactions.

The key abstraction that came out of my thinking was to express everything as objects (think HTML elements), behaviors (think patterns) and events (both events and callbacks).

In some ways it is similar to jQuery. And in fact I use jQuery for the selecting of elements. Protoscript, however, is a very stylized way to describe interactions. This makes it ideal as a building block.

For example, since the language is so simple (It is actually in JSON format) it makes it easier to extend to multiple toolkits (currently I use YUI, but I have built a simple example with Mootools), add new behaviors and events and even more importantly be able to build GUI tools on top of it.

As a first hack I created Protoscripter a bookmarklet that brings a GUI interface to any web page allowing you to play with protoscript (without any installation, other than the bookmarklet) and experiment with interactions.

I have been careful about pushing protoscript out because of this layering approach. Ideally I would have the whole stack. I would have a complete GUI as a FF extension allowing designers, product marketing or web devs to quickly sprinkle interactions onto their prototypes and quickly iterate to the best design. Well that is not reality. I have invested about 2-3 weeks of time so far and feel I have gotten it to the right level to release to the public.

There are 31 behaviors, 40+ live demos, a simple GUI tool (protoscripter). The scripting engine seems to be pretty solid (knock on wood). I have a full wiki with full documentation on all those behaviors. The code is over in Google Code in a repository ready for open source contribution.

So to kick it off I am giving a talk this morning at the Rich Web Experience here in San Jose. You can get a PDF version of my talk here: Prototype Presentation.

And most importantly start checking out prototoscript.com (right now the best experience is in Firefox).

Thursday, June 14, 2007

Simple Debugger - Based on YUI Logger

I decided to wrap the YUI Logger, add a JavaScript command line that outputs the results in a hyperlink format to facilitate simple drill down.

YUI Style Debugger

Works on IE6, IE7, FF. Haven't tested the other browsers.

Just a quick hack to make some stuff I was doing go simpler. Use it if it helps.

You can get it at my debugger page.

Tuesday, June 05, 2007

Pattern: Teaser Pattern - Carousel

Cue'ing the User


One of the challenges with the carousel is clearly delineating that there is more content hidden behind those back and forth arrows. There are a number of ways to cue the user that there is more content. You could:
  • Show a series of dots that reveal where you are (like in ifilm.com below).
    • Works best for a small set of data.
    • Good for doubling as navigation.
    • Only good for showing "1 of n" items, not "n of many"

  • Provide paging text. Something like "Showing 4 of 8"
    • Have to read to determine where you are
    • So 90's ;-)
  • Enable/Disable arrows when you reach beginning or end
    • Can be subtle depending on how it is done
    • Not always obvious to the user
    • Does not help when you are wrapping the content (since you need to keep the arrows enabled for wrapping)
  • Use a small preview of thumbnails (like the dots approach above) and show where you are in the set. Same issues as with dots.
Teaser Approach
Another approach that seems to bear out well in testing is to expose a little of the content before and after the visible items.
  • Works well for image content (since you will only get an edge it needs to be easily recognized as part of content from another page).
  • At a glance you know there is more to come
  • Makes you want to click on the next to get the full view of what is hinted at
Here is an example from my carousel.



This kind of teaser pattern can be found in lots of places.

One place that came to mind was in children's books. You know the technique. You are on a page spread and just to the edge of the page is a teaser. In What Do You Do with a Tail Like This? (Caldecott Honor Book), each page has the end of the tail just appearing on the right edge of the right page. Kids want to turn the page to see what the tail belongs to.

Another example is from the excellent book by Jan Brett, The Hat. As various articles of clothing blow off the clothesline, the animals discover them and begin to wear them. Of course the porcupine ends up with a woolen hat.

Each page has some very clever visual clues as to what is going on elsewhere in parallel with the story; as well as what comes next. Here are two page spreads. Notice the rightmost image (I have highlighted in yellow) that clues you to who comes next in the story. In this case you know the dog comes into play. You can see in the second spread this is in fact the case. (Other things are going on too. On the left the oval picture is telling what is happening with the little girl at the same time; the topmost illustration of the clothesline tells what is happening to all the clothes as they are blown off the line).





While not as entertaining as the book, this new feature is part of the 0.5.5 release of the carousel.

Enjoy.

Sunday, February 18, 2007

Ajax 101 Presentation

Just posted my Ajax 101 talk on slideshare.

I have given this talk in a number of venues starting in January 2006 with Adaptive Path in the Designing & Building Ajax Workshops we hosted in LA, Austin and Amsterdam. I also have given this within Yahoo! for internal training as well as for VeriSign, Federal Reserve, Ultimate Software, United Online and others.

To me understanding web development starts with understanding event handling, model & data services and how to manipulate the DOM. This mental framework is used in this talk (it follows the Model-View-Controller pattern from SmallTalk-80 days).

Enjoy!

Thursday, October 05, 2006

Designing a Component



I’ve designed a number of software widgets, components and gadgets throughout my career. In the early days of Mac programming I created small desktop accessories and my own set of components to enhance my application development (e.g., geographical map component, 3D graphics library).

Later in the days of Motif I wrote numerous components (spreadsheets, charts, directed graphs, server-side grids). I also made a trek through the TCL community creating components for the incr Widgets set.

I spent several years working in the world of Java Swing building components (in fact I built at least three completely different component sets for three different companies—thank God that we now see more things getting open sourced!)

I finally ended up in the land of web development taking trysts through HTC components, JSP/Struts components (tag libraries) and finally pure JavaScript components. There are a lot of lessons I have learned over the years in how to create useful components. There are three that stand out in my thinking:

  • Make the component specific in purpose, yet flexible in use.

  • Avoid the do-everything component. Instead make it do the main thing well. But make it pragmatic by keeping it flexible.

  • Separate the concerns of interface, interaction, and content.

  • Avoid hard-coding visual style, give flexibility in the interaction model and provide flexible ways to manage data content. Keep these three areas independent to allow them to be customized separately.

  • Document the interface and use the component before releasing it.

  • You know the experience. You think you have a great idea. Then when you go to explain it to another person you immediately see the holes in your logic. Documentation provides a way to explain your interface; writing demos allow you to exercise the component to test its ease of use and flexibility.

Make it Specific yet Flexible
Make the component specific in purpose, yet flexible in use.


The agile community expresses the idea of simplicity over over-generalizing. One of the traps that people fall into is trying to build a component that does everything. Not unlike feature creep in application development, a component can collapse under the weight of too many features. One of the sure signs of this is when certain parts of the API start competing with other parts of the API.

As an example, let's look at the carousel. It is just a simple list view manager. You can actually make the carousel look like a tabset or a slideshow. However, I chose not to provide additional tabset or slideshow functionality. Why? I knew from experience that the interface would become unwieldy. Lots of new configuration parameters and methods would get added that only made sense if you were using the carousel strictly in slideshow mode. You can imagine that with enough features, some of the API would only apply to these tangential behaviors. The result would be a carousel component that ends up with portions of API that don’t even apply when the carousel is behaving “just” as a carousel.

A nice way to keep a component flexible is by providing a simple configuration mechanism. The Yahoo! UI library provides a Configuration object for just this purpose. (The first time I saw this mechanism in popular use was with the Prototype library.) Instead of having to pass lots of parameters to the carousel’s constructor (new Carousel()), you pass in a configuration object. The configuration object is really just an object that contains parameters and values encoded in JavaScript object notation. Here is an example from the wrap example:

var carousel = new YAHOO.extension.Carousel("dhtml-carousel",
{
numVisible: 4,
animationSpeed: .8,
animationMethod: YAHOO.util.Easing.easeBoth,
scrollInc: 3,
navMargin: 40,
size: 17,
loadInitHandler: loadInitialItems,
prevElementID: "prev-arrow",
nextElementID: "next-arrow",
loadNextHandler: loadNextItems,
loadPrevHandler: loadPrevItems,
prevButtonStateHandler: handlePrevButtonState,
nextButtonStateHandler: handleNextButtonState,
wrap: true
}
);

Each configuration parameter has a default value. If the user provides a configuration parameter it is treated as an override and is applied to the internal set of configuration values. The carousel then uses these values in its operation.

Keep Concerns Separate
Separate the concerns of interface, interaction, and content.



If you have read other articles on my blog or heard me speak you will notice that I often fall back on this idea of separation of concerns along the lines of interface, interaction and content (or data). Sometimes I express it as feedback, interaction and information. And often I just state in the way I first learned it from the boys at Xerox as simply Model-View-Controller.

When I wrote the carousel I started with the basic understanding that I was creating a list view manager. The underlying HTML structure I chose to control was an “unordered list” (UL & LI HTML tags). Keeping my thinking general in this matter allowed me to separate several areas of concern. Here is how this concept of separation played out in the carousel.

1. Flexibility of Visual Style
First I wanted to provide flexibility in the component’s presentation. One of the ways I did this was by putting all style choices into a stylesheet (CSS). It’s really easy to hard-code style choices into the component logic. By placing style considerations externally you can help fulfill the first point above – keep it flexible. The other way the presentation was made flexible was by providing configuration parameters that select the way items are displayed. Control over the number of visible items, the animation speed and method, the size of a page of information, and the orientation are all ways that the carousel is flexible enough to adapt to most environments.

2. Flexibility of Interaction
Second, I decided that the interaction should be completely flexible. I did not want to constrain it to my choice of navigation controls or method of user interaction. In most of the current examples, previous and next arrow buttons control the carousel. While this is the normal case, it is easy enough to allow mouse over events drive the interface. The carousel exposes the same interfaces it uses internally. You can simply wire your events to the same internal mechanisms used by the carousel internally.

Microsoft Altas (now called Microsoft Ajax Framework) does a nice job of separating behavior from its components. For example, they isolated the behavior of auto complete from the components. This means that if you add this behavior to say a text field you would have an auto complete text field. It also means that you can write your own components and by obeying an interface contract, have your component support this behavior. In essense the interaction is packaged as a separate entity and just attached to the component needing the behavior.

3. Flexibility in Content
And third, I felt that there had to be flexibility in the way content gets displayed in the carousel. The simplest mechanism for this was to allow developers a way to shove their own HTML into any item in the list. The innerHTML technique is very useful in this regard. It is very friendly to PHP, JSP, ASP and other page generation techniques. It’s also the native way to express an interface on the web. What this means is that each “item” in the list could be a complete page of content, a single photo from a photo stream, a set of form elements—in short anything you want a “list item” to be it can be.

Another dimension of content is in how the data actually gets loaded. By externalizing the loading mechanism through a set of function callbacks (functions that you write that let you decide how to load the initial set of data and fetch the next and previous set of data) the component is able to support static data, client side generated data or server-side fetched data (e.g. via Ajax). Recently someone wanted to wire the carousel up to RSS feeds. Even though I had not considered RSS feeds, since the data loading was externalized, it turned out to be a fairly trivial exercise.

Test by Documentation and Usage
Document the interface and use the component before releasing it.



Alan Cooper advocates that designers design in pairs. One takes the role of Interaction Designer (ID), the other the role of Document Communicator (DC). In design sessions the ID takes the lead role in pitching ideas. The DC tries to capture the ideas and wherever there is difficulty in capturing or explaining the idea it is forced to go through some iterations to make it easier to communicate. The idea is that by having to explain your ideas. This doesn’t just work in designing user interfaces, but it also works in designing programmer interfaces.

As I am writing this blog post I am sitting next to Luke Wroblewski on a flight back from Lisbon. He saw this point in my article and reminded me of a post he wrote a while back on Nine Lessons from Nine Years of Interface Design. One of the lessons he notes is that “writing it down forces you to think it through.” On this point he summarize three good reasons for writing it down:

  • Solidifies the approach. Guards against localized decisions.

  • Articulates the rationale. Puts the solution in context of its use.

  • Ensures clarity. If you can’t explain it, then nobody else will be able to either.


I find the exercise of both documenting and writing demos for components to be refreshing. It gives you a chance to come above the code cloud and both talk to the user and be the user of the component you are writing.

I finished the first version of the carousel in just 2 days. I spent the better part of the next 2 days writing documentation and creating demos for it. All during that phase I was constantly going back and rewriting parts of the code. Documentation can seen as a kind of test-first strategy for writing APIs. Writing demos is a good way to create tutorials as well as experience what it is like to really use your component.

Of course the biggest caution I would have about trusting too much in the demo applications you write is to realize that they are only demo applications. It really takes being exercised in several real world examples to fine tune an interface.

This lesson follows something that we try to employ at Yahoo! We call it “eat your own dog food.”

The phenomona of Yahoo! Hack Day has had a profound impact on the web services and APIs throughout Yahoo! (I would go so far as arguing that this has been the biggest impact of Hack Day—causing our services and APIs to become more robust.) When the Hack Team attempted to put together a combination of our APIs (events, maps, search, etc.) they discovered just how many things were missing. The creation of just that one demo pushed the discussion of what needed to be added or corrected—-and the result is a much richer API available to everyone (public included.)

Wednesday, February 15, 2006

Open Yahoo!

I've had a few people ask us why we went public with our libraries.

Having been intimitately involved in the bringing the pattern library live I can tell you first hand the simple reasons they have gone public. And these are good reasons for others to do the same.
  • Goodwill. Sharing back with the community always pays back in rich dividends.

  • Feedback. Lots of eyes and lots of hands make the libraries better. We recognize that there are a lot of smart folks outside the halls of Yahoo!

  • Dialog. Brings issues to the forefront for discussion. Like accessibility for design; common design libraries and language.

  • Reuse. Best corporate reuse strategy is open source. I saw it at Sabre with Rico. Same at Yahoo. Already groups are using the libraries more now that they are public. And it energizes people to participate in something bigger than all of us.

  • Standards. If some of our better design ideas spread then it is good for our users and in turn good for us. Relearning different ways to do the same thing is only fun for so long :-)

  • Mindset. Yahoo! has a lot of folks in management, design & engineering that have benefited greatly from the open source community. This gets in your blood. It becomes part of your value system. So it becomes a natural reflex to do it this way.
That's basically the reasoning. No big surprise.

And yes, we don't share everything. We have lots of really awesome research going on. Really cool stuff coming. Sorry that won't be in the next release of the libraries ;-) But I think that is understandable.