Design a single page app with Ember

Steven Trevathan on how solid exploration and an awareness of design patterns are key to creating a great single-page application.

So you're about to create your first Ember application. Ember is a framework for creating web applications, and you chose it because of its speed, modularity, extensibility, and how easy it makes managing your codebase as it grows. Your choice in technology is super-sound, but you don't know where to begin with the design.

That's OK. I can help. Knowing your audience, the products they use, and any experiences similar to what you're creating is the foundation to designing a successful product. That knowledge will hint at the design direction you want to go in.

In this tutorial, we are going to pretend we're redesigning a farm share delivery application called 'SproutPass' (forgive me for the awful name) for web and mobile web. The business stakeholders want the app to enable users to select and request delivery of farm produce, text the delivery driver, and monitor the environmental impact of their transaction.

Meet your users

We'll begin assessing the experience by doing as deep a dive into the mind of the user as possible.

Learn who the users are, what experiences they have in purchasing farm shares, and why they do it. Follow tangents and let the answers flow naturally. This can be challenging if you're not exactly the social type (I sure didn't use to be), but it's a step you can almost never go without – and it's best to do it in person if at all possible. You don't know what you don't know, and talking to real users will lead you to discover those things very quickly.

Let's say we interviewed five users and found that they shared some major characteristics:

  • Economically considerate
  • Often miss produce pick-ups
  • Care about their health and the planet
  • Care about local businesses and farms
  • Started using SproutPass because produce deliveries would keep them well stocked
  • Found the UX confusing and didn't know how environmentally efficient deliveries were

Once we've learned who our users are, we can start to consider how the product we're redesigning might fit into their daily lives. At DockYard, we like to create journey maps that describe in an abbreviated way what a particular user is experiencing over the course of their day. This helps us envision many possible touchpoints for our application.

Let's do this for a user named Margaret. In the journey map above, we can see that Margaret has a few points in time where she worries about produce: at breakfast when she looks inside her fridge, while she's eating her lunch, and once she has returned home, near delivery time.

Mental models

Once we've identified the places in Margaret's journey where our app can help the most, we can start building a mental model: her mental image of a designed object and how it may be interfaced with. We'll start by thinking about analogous experiences to the problems we're going to solve for Margaret.

Do this by being specific when identifying a likeness that the user will interpret your product by. 'Like a desktop application' is not a useful model. 'Like a chat program' is better, as it's a comparative use of the application, rather than how the technology responds. The key is to define ways the user will come to understand the application.

Let's say Margaret uses an app to monitor her running performance, gets lifts around town with Uber, and uses Facebook Messenger to communicate with friends and family. These are some anchors you can use to base her assessment of SproutPass.

So let's spin this on a description of SproutPass. What if we say: 'SproutPass is a marketplace, connecting local farmers with eco-friendly consumers'? That describes what is happening with the app, but it doesn't provide a foundation to design for. We want something that gives some indication of how the UI might appear, and what Margaret might more readily understand. Maybe 'SproutPass is like a dispatch management service for produce delivery'. That's way better. We can now start to picture what the UI might be.

From these mental models, we may be able to derive design patterns for the app. In the case of SproutPass, maybe that's the map and car paradigm from Uber for monitoring a shipment. Perhaps there is a history of shipments, their environmental impact as compared to driving and picking it up themselves, and screen similar to a text message or email for communicating last minute notes to your driver.

Design patterns in Ember

This design focuses only on the indicators necessary for Margaret’s delivery, with simple ways to access more information

This design focuses only on the indicators necessary for Margaret’s delivery, with simple ways to access more information

Once we've done the appropriate research required to fully understand the landscape in which we'll be sculpting our application, we can move on to the design stage. Based on the user's context, we're able to identify some design patterns we may use as a general mould for our application.

Single-page web applications have their own technical challenges and we have design patterns for dealing with those as well. Let's look at some methods you can use to confront these challenges.

Be fast...

Use SVGs or sprites where possible, compress images, minimise style sheets and JavaScript, limit your font usage (doing so will often improve your design as well), and where possible aim to reduce the total number of requests you're making to the server. In most scenarios you want to allow users to receive a fully rendered application as fast as possible, even if their connection is slow.

... but seem even faster

The skeleton shows a basic ‘ghost’ of content that will replace it. This can be entirely CSS

The skeleton shows a basic ‘ghost’ of content that will replace it. This can be entirely CSS

Skeleton UIs are a way for us to create an experience that feels faster than it actually is. We do this by creating a bare-bones version of the content to come, which is displayed to the user while the actual content loads. Skeleton UIs can take different forms, but here we'll use basic shapes that represent the content to be loaded.

This works as a confirmation of progress. When Margaret taps to message the driver, instead of sitting on a blank page until content loads, she gets a sense that the system is working. The experience will feel like it is rolling out to her.

The skeleton has been replaced with actual content. Note there is more content than represented by the skeleton

The skeleton has been replaced with actual content. Note there is more content than represented by the skeleton

The Ember skeleton add-on enables you to experiment with creating your own skeleton UI. In the README (partly represented below) it shows how you can display fast-loading temporary images in place of the final, slow-loading image. Please note that the library relies on addEventListener and removeEventListener, which require IE9+.

First off, you need to install the add-on:

ember install ember-skeleton

Use the component in your templates:

{{skeleton-img src="/path/to/large/image.png" tmpSrc="/path/to/small/placeholder.png"}}

The workflow is as follows:

  1. The tmpSrc image will be loaded first
  2. Once complete, the src image will attempt to load
  3. If the src completes, this will be displayed
  4. If the src does not complete successfully, the tmpSrc will remain
  5. If an optional errorSrc is provided, that image will be displayed if src doesn't complete successfully

For more on this, take a look at the GitHub repository accompanying this article. Here, you'll find advice on setting defaults, styling, deferred rendering and more. You can also see a basic example in action, with a link to toggle deferred rendering here.

Be kind, rewind

There are scenarios in which Margaret may make an error. Let's pretend she accidentally cancelled a delivery she meant to schedule. Allow Margaret to use hot keys like 'cmd+Z' and/or provide a clear undo button for her to reverse her action. Absolute accident prevention is ideal, but impossible. In the cases where users can make an error, they will.

Prepare to be offline perpetually

Internet connection is something we take for granted, and often applications are designed under the expectation that a request always has a response. Our apps need to be aware of the connection state and respond to it. Beyond that, offline mode can provide an avenue for someone with very little access to the internet in general to pull the data down in one location (where they have internet) and continue to run that app elsewhere (where they don't).

Final Thoughts

You are unlikely to nail your concept on the first try. It's important that you can test your designs continuously to ensure you're providing an application that is spot on. I recommend doing several design sprints to rapidly explore and test possibilities before burning too much time developing your app.

Words: Steven Trevathan

Steven Trevathan is Partner and creative director at DockYard. This article was originally published in issue 269 of net magazine.

Here's a video to go with this tutorial:

Liked this? Read these!