Prototyping

Determine the Purpose

When starting to work on a prototype, it is important that the client and the Involution team are clear on the purpose of the prototyping endeavor.

Based on the purpose, you need to take different approaches.

Goal A: Validate and Improve the Design

If your goal is to validate and improve the design, it is important to focus on rapid iteration. There is a lot of value in prototyping as part of the design process. It forces the design team to think about micro-interactions (i.e. hover states, transitions, labels) that they might have overlooked while designing on paper. It also lets you experience a design in its native format. Some designs that looks great on paper fail horribly when they start living and breathing.

If the goal is really to let the design team (including the client’s core team) validate and iterate on the design, then the prototype might not need to be as polish or as complete. For instance, if evaluating a workflow, you might not need to implement each of the steps in order to evaluate the success or failure of the design. In some cases, though, these steps might be critical to evaluating the success or failure of a design.

Some of the best prototypes in this scenario have razor-sharp focus on specific areas of functionality. You can save a lot of time by building a bunch of small prototypes rather than one large prototype.

Goal B: Sell the Design to Customers or the Organization

Oftentimes, a client needs help communicating the new design throughout their own organization or to their customers. Prototypes can be a great way to achieve this. In some cases, our clients’ sales teams have used our prototypes to sell the future of the product while the production system is still in development.

When building a prototype with the goal of the client using it for demos to customers, it is critical to work with the client to define the story or stories they will tell while using the prototype. When scoping the prototype, the story will be used to decide what is critical to nail, what can be faked, and what doesn’t need to be included.

Goal C: Identify Technical Feasibility

If your goal is to test the technical feasibility of a design (or a portion of a design), it is important to make sure you have a good understanding of what the final technology stack might look like. Is there an API? Is it a native application? It is going to be built in the style of a single page application?

Determine the Scope

It isn’t possible to prototype everything and rarely does it make sense to. You should be prototyping for a purpose.

Technical Questions

General Rules

Common Pitfalls

Incorrectly Attributing Feedback

Sometimes clients (or Invoites) see a prototype that is a bit laggy or doesn’t quite feel right and take it as a failure in the design. When incorporating feedback from a prototype, it is important to understand the root cause of the feedback. For instance, if someone is having trouble using inline editing, it could be because inline editing doesn’t make sense in this context or it could be because the specific code implementation of the inline editing isn’t right. It is easy to incorrectly evaluate feedback on a prototype and end up making bad design decisions.

It isn’t that the feedback isn’t valid… it just indicates where a little more attention might need to be focused. For instance, if the feedback loops (for submitting items) feel laggy in a prototype, it might mean that you need to pay more attention in how the saving of items is handled in the production application.

Mistaking the Prototype’s Performance for the Expected Production Performance

Focusing on Details that Don’t Matter

The scope of prototypes can explode if you focus on details that don’t matter. When you are building a prototype, you need to constantly ask whether what you are working on adds value towards the goal of the prototype. If it doesn’t, it might not need to be implemented or it might be able to be faked.

Not Enough Technical Architecture

You don’t want to spend too long on technical architecture for the prototype, but if you don’t spend enough time you will find yourself with a fragile and stapled together system which is hard to maintain. Some common pitfalls with this:

Data

When someone is evaluating a design they use the data as well as the design elements in the screen to understand the design. As such, it is important that your prototype contains real data which tells a story.

Properties of Real Data

In your prototypes it is important to use real (or at least realistic) data. The best option is to have get real data from the client. In cases where this isn’t available, you can craft a dataset.

At the most basic level, consider these:

Some Techniques

InDesign DataMerge

Adobe InDesign (and Illustrator) have a feature called DataMerge. It allows you to turn a design file into a template and batch generate InDesign files with the data provided in a CSV file. These files can be linked to other designs (using the Place command) or exported as images.

In javascipt, you can then do something like this:

//Assume we've placed our generated images in images/ directory.
var i, html;
var numItems = 150;
for(i=0; i<numItems; i++){
	//Better to use a real templating language.
	html = '<div class="singleItem"><img src="images/item_'+i+'.png"></img></div>';
	$('#allItems').append(template);
}

Then you can add some interaction with some CSS

.singleItem{
	background-color:#f2f2f2;
}
.singleItem:hover{
	background-color:#444;
}

You can also add some javascript interactions. Assume that we also exported item_expanded_1.png, item_expanded_2.png, etc. When we select a row, we want it to expand.

A Mustache template:

<script type="text/html" id="rowTemplate">
{{#items}}
	<div class="singleItem" data-expanded="no">
		<img src="img/item_{{num}}.png">
		</img>
		<img class="expansion" src="img/item_expanded_{{num}}.png">
		</img>
	</div>
{{/items}}
</script>

We can populate it for our 150 images like so:

var numItems = 150;
var i=0;
var allObjects = [];
for(i=0; i<numItems; i++){
	//Make this an object so we can add more properties in the future if we want.
	allObjects.append({num:i});
}
var template = $('#rowTemplate').html();
var generatedHTML = Mustache.render(template, allObjects);
$('#allItems').append(generatedHTML);

$('.singleItem').click(function(e){
	var isExpanded = $(this).attr('data-expanded') === 'yes';
	if(isExpanded){
		//We are expanded already, so let's close it.
		$(this).attr('data-expanded','no');
	}
	else{
		//First, close everything else.
		$('.singleItem').attr('data-expanded','no');

		//We aren't expanded, so let's open it.
		$(this).attr('data-expanded','yes');
	}
});

Add a bit of CSS

.singleItem[data-expanded="no"] .expansion{
//Don't show the expansion image if we are not expanded.
	display:none;
}

Now, we’ve built an expandable table with only a few lines of code. You could even add a CSS transition to make it animate on expansion.