A question of timing

I’ve been updating my collection of design principles lately, adding in some more examples from Android and Windows. Coincidentally, Vasilis unveiled a neat little page that grabs one list of principles at random —just keep refreshing to see more.

I also added this list of seven principles of rich web applications to the collection, although they feel a bit more like engineering principles than design principles per se. That said, they’re really, really good. Every single one is rooted in performance and the user’s experience, not developer convenience.

Don’t get me wrong: developer convenience is very, very important. Nobody wants to feel like they’re doing unnecessary work. But I feel very strongly that the needs of the end user should trump the needs of the developer in almost all instances (you may feel differently and that’s absolutely fine; we’ll agree to differ).

That push and pull between developer convenience and user experience is, I think, most evident in the first principle: server-rendered pages are not optional. Now before you jump to conclusions, the author is not saying that you should never do client-side rendering, but instead points out the very important performance benefits of having the server render the initial page. After that—if the user’s browser cuts the mustard—you can use client-side rendering exclusively.

The issue with that hybrid approach—as I’ve discussed before—is that it’s hard. Isomorphic JavaScript (terrible name) can theoretically help here, but I haven’t seen too many examples of it in action. I suspect that’s because this approach doesn’t yet offer enough developer convenience.

Anyway, I found myself nodding along enthusiastically with that first of seven design principles. Then I got to the second one: act immediately on user input. That sounds eminently sensible, and it’s backed up with sound reasoning. But it finishes with:

Techniques like PJAX or TurboLinks unfortunately largely miss out on the opportunities described in this section.

Ah. See, I’m a big fan of PJAX. It’s essentially the same thing as the Hijax technique I talked about many years ago in Bulletproof Ajax, but with the new addition of HTML5’s History API. It’s a quick’n’dirty way of giving the illusion of a fat client: all the work is actually being done in the server, which sends back chunks of HTML that update the interface. But it’s true that, because of that round-trip to the server, there’s a bit of a delay and so you often end up briefly displaying a loading indicator.

I contend that spinners or “loading indicators” should become a rarity

I agree …but I also like using PJAX/Hijax. Now how do I reconcile what’s best for the user experience with what’s best for my own developer convenience?

I’ve come up with a compromise, and you can see it in action on The Session. There are multiple examples of PJAX in action on that site, like pretty much any page that returns paginated results: new tune settings, the latest events, and so on. The steps for initiating an Ajax request used to be:

  1. Listen for any clicks on the page,
  2. If a “previous” or “next” button is clicked, then:
  3. Display a loading indicator,
  4. Request the new data from the server, and
  5. Update the page with the new data.

In one sense, I am acting immediately to user input, because I always display the loading indicator straight away. But because the loading indicator always appears, no matter how fast or slow the server responds, it sometimes only appears very briefly—just for a flash. In that situation, I wonder if it’s serving any purpose. It might even be doing the opposite to its intended purpose—it draws attention to the fact that there’s a round-trip to the server.

“What if”, I asked myself, “I only showed the loading indicator if the server is taking too long to send a response back?”

The updated flow now looks like this:

  1. Listen for any clicks on the page,
  2. If a “previous” or “next” button is clicked, then:
  3. Start a timer, and
  4. Request the new data from the server.
  5. If the timer reaches an upper limit, show a loading indicator.
  6. When the server sends a response, cancel the timer and
  7. Update the page with the new data.

Even though there are more steps, there’s actually less happening from the user’s perspective. Where previously you would experience this:

  1. I click on a button,
  2. I briefly see a loading indicator,
  3. I see the new data.

Now your experience is:

  1. I click on a button,
  2. I see the new data.

…unless the server or the network is taking too long, in which case the loading indicator appears as an interim step.

The question is: how long is too long? How long do I wait before showing the loading indicator?

The Nielsen Norman group offers this bit of research:

0.1 second is about the limit for having the user feel that the system is reacting instantaneously, meaning that no special feedback is necessary except to display the result.

So I should set my timer to 100 milliseconds. In practice, I found that I can set it to as high as 200 to 250 milliseconds and keep it feeling very close to instantaneous. Anything over that, though, and it’s probably best to display a loading indicator: otherwise the interface starts to feel a little sluggish, and slightly uncanny. (“Did that click do any—? Oh, it did.”)

You can test the response time by looking at some of the simpler pagination examples on The Session: new recordings or new discussions, for example. To see examples of when the server takes a bit longer to send a response, you can try paginating through search results. These take longer because, frankly, I’m not very good at optimising some of those search queries.

There you have it: an interface that—under optimal conditions—reacts to user input instantaneously, but falls back to displaying a loading indicator when conditions are less than ideal. The result is something that feels like a client-side web thang, even though the actual complexity is on the server.

Now to see what else I can learn from the rest of those design principles.

Have you published a response to this? :

Responses

KyleWm

@jgarber Someone needs to put this caption on a pic of Spock reaching out to Kirk at the end of Star Trek 2

# Posted by KyleWm on Tuesday, January 27th, 2015 at 7:59pm

Jason Garber

I’ve been building things on the Web for something like eighteen years. That’s greater than half my lifetime. On my bookshelf at home, I keep my nearly 20-year-old copy of HTML for the World Wide Web. I clearly remember buying—with actual dollars—a boxed copy of Netscape Navigator at a store that only sold software. Angelfire hosted the first website I remember piecing together.

Needless to say, I’ve been around the ol’ block.

I tell you these things not to brag or to date myself, but to give you a sense of my background and where I’m coming from when I talk about designing and developing for the Web. While reflecting on my career and experiences, I came up with a brief list of professional self-improvement tips for anyone working on the Web today.

  1. Know Your History

I’m a history geek through and through with a particular interest in the 20th century and the development of the technology that powers our modern world. In order to understand how we got to now, you have to have a curiosity about the past.

I’ve recently read two Internet- and Web-themed history books: Where Wizards Stay Up Late, a chronicle of the development of the ARPANET, and Weaving the Web, a first-hand account of the Web’s creation by Sir Tim Berners-Lee. Both are rich with insight and packed with the philosophies imbued in the foundations of the Internet and the Web.

If you want to delve further back in time, read Vannevar Bush’s 1945 essay As We May Think or watch Douglas Engelbart’s 1968 Mother of All Demos. If fiction is more your speed, read the works of Arthur C. Clarke and Robert Heinlein. Both wrote of technology that, while unheard of in their time, is essential to modern life. Talk about inventing the future!

Lastly, if reading isn’t your thing, check out Brian McCullough’s Internet History Podcast which covers “modern” Web history starting with the introduction of the Mosaic web browser and its evolution into Netscape Navigator.

Only through a love of history can you begin to make the connections from pre-World War II science fiction to daily life with a smartphone in the 21st Century.

  1. Know Your Medium

Each speciality within the vast umbrella of “Web professional” carries with it a long list of critical knowledge. For example, visual designers possess an understanding of typography and a mastery of design tools that I never will. I would eat the brains and gain the knowledge of any professional copywriter if I thought doing so would give me a better command over the written word.

Maintaining a conversational knowledge of these sorts of topics is of great utility, though. Knowing the basics allows you to move gracefully between disciplines, shifting conversations and language depending on with whom you’re speaking. Be comfortable talking color and font choices with a visual designer. Be equally comfortable chatting with a developer about the most appropriate way to mark up or style a design element. Moving effortlessly between these kinds of conversations greatly reduces friction between disciplines and makes you a very valuable member of the team.

On the technical side, a lack of familiarity with underlying Web technologies often leads to undue aggravation and misunderstandings between team members. It’s my view that everyone working on the Web would be better off with a base-level understanding of:

The Web’s building blocks—HTML, CSS, and JavaScript—and the role each plays. How a Web browser requests resources and interprets each for presentation to the user. How servers—web, database, etc.—work together and respond to requests. How networks—particularly cellular-based mobile networks—behave and how their behavior impacts users. To reiterate: I don’t expect everyone to master these topics. I know comparatively little about managing servers and network infrastructure makes my head hurt, but I am familiar with the various kinds of servers used to build Web things and I conceptually understand the impact of network latency on data delivery.

I recently explained to a teammate the relationship between web servers, web application frameworks, and database servers and it made me feel awesome when the lightbulb clicked for her and she understood the differences between each. Be that person on your team or in your organization. Better still, inspire others to share your passion for learning.

  1. Respect Those Who Came Before You

Think you’ve got it bad because you can’t decide which monolithic JavaScript framework to use or which Node-based build tool to throw at your project? Try convincing the largest companies in the world that their little Web browsers should properly support CSS Level 1.

The Web of the late ‘90s was a nightmare hellscape of proprietary markup and closed-source implementations; a world devoid of standards (as we know them today). To this day, I shiver thinking back to when there were two completely different and incompatible DOMs: Netscape’s and Internet Explorer’s. Ugh.

Working on the Web during the Browser Wars was difficult. The Web was littered with banners and badges proclaiming which of the two major browsers a website supported. I’m absolutely guilty of this: Netscape was my browser of choice. The commercialized Web was failing its creator’s desire for universality and accessibility.

Folks like Eric, Molly, Jeffrey, Glenda, Jeremy, Kimberly, and countless others tirelessly fought for the Web on our behalf. It’s thanks to their efforts through organizations like the Web Standards Project that we today enjoy building websites for browsers that, on the whole, conform to an agreed-upon set of standards.

Take the time to familiarize yourself with the work of the previous generation of Web designers and developers. We’re fortunate in our industry that most of this previous generation are still active in the field and are happy to share what they know. Learn from their successes and failures.

  1. Respect Your Audience

In his recent post, A question of timing, Jeremy Keith writes:

I feel very strongly that the needs of the end user should trump the needs of the developer in almost all instances.

A++, would quote again. Jeremy’s speaking specifically about front-end frameworks that allow for rapid development of so-called “web apps.” I’ll take his statement a step further and apply it to our entire design and development process.

It’s concerning that so much web design and development occurs on the largest, most color-accurate displays available driven by the latest hardware jacked straight into the Internet via an always-on broadband connection. To be fair, these conveniences make development a breeze, but they don’t reflect our users’ reality. While some of your audience may be using cutting-edge desktop computers, a growing number of people are mobile-only users.

Ask anyone with a Comcast—err, XFINITY—Internet connection about the reliability of their service. Ask anyone with a limited-bandwidth mobile data plan about exorbitant overage charges. For that matter, ask anyone who lives in a rural area about their cellular network coverage. Travel anywhere outside of the United States and these challenges are just the tip of the iceberg.

As the next billion people get online, our work will be ruthlessly judged by how quickly and reliably it loads. How much that matters to you—or your client—may depend on the nature of your work. A commercial website selling shoes to wealthy Westerners clearly has a different audience than a non-profit providing citizens with access to critical health information. However, a reasonable person would be hard-pressed to come up with valid reasons to intentionally slow down access to their website, regardless of the nature of its content. It behooves us all to set aside our many conveniences and better empathize with our users.

To help with this, I’ve found it useful to develop a set of principles. Jeremy maintains a collection of design principles he’s curated from around the Web. Give them a read; they’re great. You’ll notice the frequent use of words like “people” and “human” throughout.

Brad Frost lays out a solid set of design principles in his recent post, Over It:

Keep things simple. Build to standards. Use progressive enhancement. Don’t try to send wheelbarrows full of JavaScript down the pipes unless you have to. Don’t make assumptions.

Remember: The websites we build are ultimately for people, not browsers or devices. Respect your audiences’ capabilities, their time, their attention, and their bandwidth.

  1. Get Involved

There are a bunch of ways to actively involve yourself. A few ideas:

Attend a local design-related event. There are others like you and they enjoy talking about what they do. Find your local Refresh. No events in your area that pique your interest? Start your own! Odds are good someone nearby shares your passion. Upend the patriarchy! Make it a point to promote diversity in our industry in whatever way you can. Talk to students at your local school or university. Get kids interested in technology. Contribute to open source projects. There are many ways to get involved in open source projects that don’t involve code. Una KravetsOpen Source Design post is a great start. There you have it: five easy ways to be a better Web professional. This list is by no means exhaustive and I’m certain you have tips on being a better professional drawn from your own experiences. I’d love to hear about them.

Many thanks to Trevor Davis and Una Kravets for reviewing early drafts of this post.

Jason Garber

Yesterday’s experience layers post—cross-published to Viget’s Inspire blog—was overwhelmingly well-received by friends and colleagues (Mom said I sounded real smart!). It wasn’t without its detractors, though.

Over on Inspire, my supervisor Doug took issue with several of my key points. Doug’s a brilliant web designer and a friend, but on the matter of progressive enhancement, he and I couldn’t be farther apart. I’m grateful he took the time to comment, giving me an opportunity to revisit my original post’s thesis.

Doug’s lengthy comment covers quite a bit of ground and I’d like to address several of his remarks. His main gripe is my use of Vine’s broken video page as a foundation for a conversation about progressive enhancement.

Doug’s right that my Vine example is cheeky:

Credit card numbers weren’t lost, data wasn’t destroyed, users weren’t endangered.

But what if the example used were a bank? Or an online store? Or a service providing health care information to the disadvantaged?

Vine merely provided a basic example of a larger issue. Websites should not rely on JavaScript for delivering primary content, even if that content is a goofy six-second video.

I bet Vine’s engineers would consider a little JS-related downtime a reasonable tradeoff for the advantages of building JS-first.

I’ve previously quoted Jeremy Keith on this topic and I’ll do so again:

I feel very strongly that the needs of the end user should trump the needs of the developer in almost all instances.

Without knowing the particulars of Vine’s development team, I feel safe hypothesizing that they chose to rely on JavaScript for displaying primary page content as a convenience to themselves at the expense of their users. I’d be interested in learning more about their decision-making process.

[Vine’s] failure was preventable — even a single integration test should catch a catastrophic bug like this.

True! Thorough test coverage can catch mistakes like the one we saw on Vine’s video page. A website serving primary content in HTML and treating JavaScript as an enhancement, though, requires less testing and is less prone to this sort of catastrophic failure.

In 2015, I don’t think JavaScript is an enhancement — it’s the baseline.

I couldn’t disagree more. In 2015, the landscape has never been more hostile. The proliferation of devices, the unreliability of mobile data networks, and the hostile nature of browsers demand that we build robust and reliable websites. Treating JavaScript as a baseline for displaying a website’s core content doesn’t square with reality.

I’m not advocating that we abandon JavaScript; far from it. As Christian Heilmann remarked, modern websites “all become better when enhanced with JS.” JavaScript plays an important role in Web development, but it should always be treated as an enhancement.

(Also: check out Christian’s The “Web Application” Myth for more on this topic.)

Users have it turned on.

Jake Archibald pointed out that progressive enhancement is not about whether or not a user has JavaScript enabled. Jake’s post is a favorite of mine and worth a read.

It runs fast.

True again! However, it’s important to remember that executing JavaScript consumes a great deal of energy on mobile devices. I’d much rather build websites that don’t place significant energy burdens on users’ devices.

Regarding the Vine example, I took a look at the page’s source and was heartened dismayed to find that the content is in the markup:

<video src="https://v.cdn.vine.co/r/videos/65B585E5BE1176418784886628352_2265f312907.5.1.14774757561628941091.mp4?versionId=zAjo2cpXw7AocL9pyw_0uTWOZkkPZCXJ"></video>

Why, then, didn’t the content display even with the JavaScript error? Glad you asked. The entire page is wrapped in this little bit of gold:

<div style="display: none">

I remain unconvinced that abandoning progressive enhancement in favor of JavaScript-first development is better for users or is the direction the Web is inevitably heading. It’s our responsibility to do right by the billions already online and the next billion preparing to come online. We can achieve this by designing robust, resilient, layered experiences using techniques like progressive enhancement.

# Posted by Jason Garber on Wednesday, February 11th, 2015 at 10:27am

11 Shares

# Shared by ᎷᏞ on Tuesday, January 27th, 2015 at 7:08pm

# Shared by Jeremy Keith on Tuesday, January 27th, 2015 at 7:24pm

# Shared by Vasilis on Tuesday, January 27th, 2015 at 7:28pm

# Shared by Angel on Tuesday, January 27th, 2015 at 7:30pm

# Shared by Ben Fino-Radin on Tuesday, January 27th, 2015 at 7:32pm

# Shared by Ty Hatch on Tuesday, January 27th, 2015 at 7:32pm

# Shared by Zach Leatherman on Tuesday, January 27th, 2015 at 7:44pm

# Shared by John Locke on Tuesday, January 27th, 2015 at 9:08pm

# Shared by Dan Thomas on Tuesday, January 27th, 2015 at 9:17pm

# Shared by Chris Vernon on Wednesday, January 28th, 2015 at 8:16am

# Shared by Roost on Thursday, January 29th, 2015 at 7:43pm

15 Likes

# Liked by ᎷᏞ on Tuesday, January 27th, 2015 at 7:18pm

# Liked by Ethan Marcotte on Tuesday, January 27th, 2015 at 7:27pm

# Liked by Paul Mederos on Tuesday, January 27th, 2015 at 7:27pm

# Liked by Ty Hatch on Tuesday, January 27th, 2015 at 7:43pm

# Liked by Taher Chowdhury on Tuesday, January 27th, 2015 at 7:43pm

# Liked by Marty Stake on Tuesday, January 27th, 2015 at 8:10pm

# Liked by Adam Hollister on Tuesday, January 27th, 2015 at 8:47pm

# Liked by Gabor Lenard on Tuesday, January 27th, 2015 at 9:06pm

# Liked by John F Croston III on Tuesday, January 27th, 2015 at 9:36pm

# Liked by Ivan Wilson on Tuesday, January 27th, 2015 at 10:24pm

# Liked by Glen Maddern on Wednesday, January 28th, 2015 at 4:34am

# Liked by Matthew Read on Wednesday, January 28th, 2015 at 4:34am

# Liked by Daniel Rehn ✖ on Wednesday, January 28th, 2015 at 6:35pm

# Liked by Luke Stevenson on Friday, January 30th, 2015 at 8:22pm

# Liked by murmurs on Tuesday, May 5th, 2015 at 6:58pm