Designing & building products you can measure

Brandon
6 min readJan 19, 2020

--

Photo by David Travis on Unsplash

Every product team I know swears by “data-driven decision-making.”

In broad strokes, that process might look something like this:

  1. Study how your users use your product
  2. Form a hypothesis about what to build next
  3. Do / build as little as possible to collect the data needed to test that hypothesis
  4. Measure, repeat

Pretty straightforward. In practice, though, even the most rigorous product teams cut corners here, relying on intuition instead of data. The gains from those shortcuts can be short-lived, though, and poorly researched decisions can create re-work we could’ve avoided by doing our homework upfront. “Measure twice, cut once” and all that.

Some companies try to prevent this sort of design-by-gut with rigorous review processes, demanding numbers before engineering resources are granted. This can work wonders in a bigger company, but the overhead it adds makes it much less practical for a smaller company.

Over the years, I’ve found a nice middle ground in simply making my products easier to measure. The core idea here isn’t terribly profound: make measuring product results easier, and we’re less likely to skip it.

The basics of event tracking

My experience is mostly with web applications, but I think most of these ideas should translate pretty well to any user interface.

The most basic form of measurement with web applications is the page view. When a user lands on a certain URL, a bit of data is sent to a server somewhere detailing who that user is and what the page was about. This is basically how Google Analytics works.

For more complex web applications, simple page view tracking usually isn’t enough. Depending on your app, your user might have a dozen different actions or intents on a single view in your app — all without triggering a page transition.

This is where “custom events” come into play. With custom events, we can send arbitrary data to a server whenever we want, not just when the user changes pages.

Now, we could use Google Analytics to track custom events, but it’s not really the best tool for the job. Instead, we look to tools built specifically for the task: Amplitude (my favorite), Mixpanel, etc. These tools offer much more robust support of custom event tracking, and really should have a prominent place in the toolbox of any data-driven team.

Tip 1: Make user event tracking the default

The downside of custom event tracking is that it typically takes engineering time to define the conditions and details of an event. When engineering hours are in short supply, this can be a major roadblock to proper product measurement.

Track everything

We can get around this roadblock by building our product in a way that creates user event data with every deliberate action the user takes. That is, if your analytics solution supports this feature.

Some solutions, like Heap Analytics, put this “track everything” philosophy at the core of their product, tracking every single move your users make. In my experience, this is a fantastic solution if your app has a pretty straightforward interface (like an e-commerce site), but not so great if your app has a lot of dynamic context (like a chat app).

Make every event a page view

If this sort of omni-tracking solution isn’t an option, your engineers might be able to help by connecting app events to the URL. To explain what I mean, consider a web app with a simple modal:

In most single page application architectures (which is likely what you have if you’re using Vue, React, Angular, etc.), the developer can choose to open this modal either by changing the URL of the page or by updating a variable in the program that’s invisible to the user.

When faced with this decision, I almost always prefer the URL. This is because you’re most likely already tracking page views, so an event is being sent whenever the URL changes. This means that when a user opens the modal, a user event records a page hit for the /app/modal route without any additional effort from the engineer.

Of course, there are trade-offs here, and you should trust your engineers’ advice on how to navigate those trade-offs.

Tip 2: Single responsibility principle for UIs

The “single responsibility principle” is a software engineering convention that basically states a thing should do one thing, and do it really well. This is helpful for writing more modular and maintainable code, but it’s useful in UI design as well.

Forms are a great example here. Imagine your team had to build a form, and they’ve elected to keep everything in a single page.

It’d be pretty easy to track how many users started & submitted the form. But which form questions see the most users drop-off? How long does each question take? Which charts do users care about the most? Adding tracking events to answer those sorts of questions might add ugly complexity to the form’s code, making it harder to build & maintain.

Now, consider a form implemented using Typeform’s signature style:

If we were to build a form like that, our engineering team could put each question at a separate URL, giving us free page view events with every question (since we’re likely already tracking page views).

Of course, you might reasonably argue that this compromises UX, and makes the product less user-friendly. While this may be true in some cases, the goal here is to build better products in the long run. Since data helps us do that, this might be a trade-off worth considering.

Action gating

Re-arranging content (as in the last example) is a great use of a product design tactic I call “action gating.” To illustrate this concept, consider LinkedIn’s profile page:

Like the form above, we can easily count how many users view this page, but how could we determine which info visitors cared about the most? Our best bet would be to try and detect where the visitor’s attention was (e.g., with scroll position), but in my experience, this is unreliable.

Now consider LinkedIn’s UI for getting someone’s contact info. Note how they’re making users perform an action before handing over the info:

It’s now perfectly clear what the user’s intent was. This is the nice thing about action gating: because we’re making the user declare their intent with their actions, it takes most of the guess work out of divining user intent.

Again, there are trade-offs with the user experience to consider here, so use your best judgment.

The scourge of under-used features

I’ve never seen a product that didn’t have features that users ignored. Too many underused features can add friction to a product’s UX, but worse, they can be a drag on the product team. No team likes working on features that users don’t care about.

We know that rigorous measurement can keep these underused features out of our products, but sometimes it’s hard to practice what we preach. By making small adjustments like the ones outlined here, though, we can make measurement second nature, keeping our products and teams lean & mean.

--

--