Threads in Slack, 一段漫长的设计旅程

Threads in Slack, 一段漫长的设计旅程

2014年8月19日上午11:46,Slack的首席执行官Stewart Butterfield创建了一个名为#feat-rxns的新频道,并邀请Slack团队的一些成员加入对话。这个频道的目的是在Slack中建立两个新功能。表情反馈和Threads。3年多以后回过头来看,这两个功能被合并到一个项目中可能听起来很奇怪,但当时听起来这两个功能都没有大到足以支撑一个以上的频道。它们都围绕着同一个想法:对信息做出反应,用文字或表情符号。

这就是设计Threads的故事,我们低估了它的复杂性。这也是对Slack设计过程的深入探讨。

所以 threads 是什么?

Threads 是我们要求最多的功能之一,但我们很早就意识到,"在Slack中拥有thread "可能意味着很多不同的东西。我们日常使用的大部分工具都以 threaded 对话为核心。Facebook、Twitter、Reddit、YouTube(当然还有电子邮件)。然而,它们各自有不同的方式来处理这一功能。

当时,Facebook的帖子每条都只有一条长长的评论线,按日期排序。在Twitter上,任何一条推文都可以有众多的直接回复,这些回复也可以有回复无穷无尽。Reddit,对待回复及其可见性也略有不同。那么,哪种方法才是适合我们的呢?

在所有这些不同的系统中,我们想先了解人们是如何理解 threads 在 Slack 中的意义。当时,Slack还不到一年的时间,如果快速迭代一些东西看到用户反馈,那是很有意义的。但Slack在没有threads的情况下运行得相当好,所以我们决定花时间去琢磨一个能给人们使用Slack的方式带来最大价值的模式。

在Slack,我们非常自豪的一点是,对于我们构建的每一个功能,我们都会在自己身上试用,然后再向公众开放。我们鼓励每个人提供关于新功能的反馈,无论你是公司里的谁。通常情况下,最有价值的反馈来自于不知道这个功能是什么的人,因为他们会以最坦诚和最真实的方式体验这个功能。这个系统也为设计团队提供了一点回旋余地:如果我们对某件事情没有把握,我们就尽最大努力去做,看看效果如何。

这个过程对于Threads来说是至关重要的,如果没有看到真实的人如何使用它,就不可能验证我们的任何设计决定。我们在内部发布了6个主要版本的Threads,每次都能得到宝贵的反馈。每一次的发布都是必要的,以便了解什么是无效的,什么是有效的。

Exploration 1 — The Twitter model, inline.

我们决定基于与Twitter相同的模型开始对Threads的第一次探索,因为它看起来是最灵活的解决方案。设计遵循了以下规则。

  • 你可以回复任何消息,包括其他的回复。
  • 一条信息可以有多少个直接回复是没有限制的。
  • 所有的回复都发布在频道里

这是我们心中的一个例证。

image

有了这个系统,你可以在频道中同时发生多个对话。我们喜欢第一种方法,因为对话被保留在频道中,并且回复与普通消息的规则相同:它们会将频道标记为未读,而提及会触发频道上的提醒。我们需要做的就是确保回复有明确的标签,这样就不会降低正常的阅读体验。

第一个版本的主要问题是,当你打开一个 thread 时,你会遇到 "展开"的效果。因为我们是上下推开消息来显示 thread 的,所以在关闭线程时很容易失去之前所在的位置 —— 尤其是当你阅读线程时总是会滚动一下,而关闭 thread 会让你处在频道中一个完全不同的位置。这对我们来说太过混乱,以至于无法判断这个功能的其他部分,所以这个方案算是黄了,我们需要继续探索。

Exploration 2 — Twitter model, overlay.

我们接下来尝试用叠层的方式显示 threads ,而不是将内容上下推开,我们相信通过将 threads 分离到自己独立的一层中,会更容易浏览频道的内容。

image

遗憾的是,这个方案解决了上面说的迷失位置的问题,却带来了更多的问题。事实证明,必须不断地打开和关闭覆盖层是非常糟糕的,而且仅仅是阅读一个频道就需要很多额外的工作。另外,让每条信息都可以点击也是一个很大的问题,因为人们经常无缘无故地点击。叠层不断地被错误触发(无论是用户试图从菜单、选择中点击,还是在阅读信息时随意点击),这非常令人沮丧。最终,我们决定不再坚持使用叠层,并将线程移到右侧侧栏。

Exploration 3 — Twitter model, right sidebar.

将主题移动到右侧边栏对工程团队来说是个好消息。用最少的努力,我们就有了一个新的地方来查看线程,而不需要移动内容或在界面上增加额外的层次。

image

因为我们使用的是一个熟悉的元素,所以我们收到的反馈开始从对用户界面的评论转变为对用户体验的评论。这不是关于功能的外观,而是人们体验该功能时的感受这是一个好的迹象,因为这意味着人们开始使用Threads,而不仅仅是从外观评论它们,但人们遇到的困惑数量是相当令人担忧的。起初,我们相信,如果我们花足够的时间打磨工作流,设计最终会开始变得合理。不幸的是,几轮之后,我们意识到,反馈不会变得更好,我们需要继续迭代。

虽然很难承认,但我们最初的解决方案都不成功。当一个团队遇到这样的壁垒时,自然的反应是质疑我们工作的必要性。我们是否应该继续?这是个好主意吗?我们是否在找事儿?我们是否应该忘记这一切,专注于下一个大功能?

设计团队花了9个月的时间来构建Threads,但现在是时候面对一个残酷的现实了:我们的模型根本无法工作,无论设计在视觉上有多么的精致。我们决定从头开始 —— 但在此之前,我们花了一些时间来开发几个小功能,这些功能是支持 Threads 和 emoji reactions 所必需的。我们还决定进行一些用户测试,以更好地了解我们的模型为什么会失败。

Message Actions

在尝试下一种方法之前,我们增加了对消息进行操作的功能,这就解决了误开 threads 的问题,并且增加了一个明显的 threads 开始的地方。

image

这让同时进行的其他几个项目受益匪浅,比如前面提到的Emoji Reactions项目,以及Share Messages项目和Reminders。有了内联动作,我们就可以继续进行用户测试了。

User Testing

为了更好地了解我们的模型为什么会失败,我们决定进行一轮小型的用户测试。在这些测试中,人们在使用Threads时遇到了和Slack团队一样的困惑 —— 设计非常复杂,人们根本不懂。如下图,这是一个 Threads 的样子。

image

因为你可以回复任何消息,包括回复,所以Threads很快就变得非常复杂。当我们意识到这一点后,我们决定限制每个Threads只能有一级回复,希望这样做可以在开始一个 Threads 的时候足够简单

image

Exploration 4 — One-Level Threads

将每个 thread 减少到只有一个级别的回复,在各方面都立即获得了成功。设计更简单,更容易建立,当然也更容易理解和使用。

image

虽然人们对这种方式不那么困惑了,但一个意想不到的问题开始出现了:人们过多地使用Threads,这让频道变得非常难以理解,因为多个对话不断地相互交织在一起。

在Threads之前,如果用户想要回复一条旧的消息,就必须开始一条新的消息,并附上一些上下文,比如 "关于这个话题,我认为......",这很容易读懂。但现在Threads承担了提供上下文的重任,人们不屑于这样做,这使得频道在不打开频道中的每个线程的情况下,变得非常难以阅读。

我们尝试了一些设计来解决这个问题,比如在回复前加上序言以提供更好的上下文,或者在频道中发布通知(比如 "Hubert已经回复")来代替回复。

image
image

不幸的是,我们的解决方案都没有产生任何真正的积极影响。无论它是如何呈现的,Threads都会让你多次阅读信息,因为你会阅读一个 Threads,然后在频道中再次阅读该 Threads 的回复。这个本应有助于阅读频道的功能,却做了完全相反的事情。我们的模式又一次失败了。由于在频道中发布回复永远不会奏效,我们决定探索完全删除它们。

Exploration 5 — Sidebar Conversations

在我们接下来的迭代中,回复只发布在侧栏,而不是在频道中。这在视觉设计和工程设计上都是对该功能的重大简化。但我们又面临着一个新的问题。在我们之前的所有探索中,一个新的回复会将频道标记为未读,所以当用户的对话正在继续时,他们会被提醒。现在回复已经不在频道里了,我们不能再依赖这个系统,但我们仍然需要一种方法来让用户知道新的回复何时到来。我们决定将线程通知移到右上方的活动面板上。

image

将回复隐藏在频道内容中,原来是我们在设计Threads时做的最有意义的一个改变。频道再次变得容易阅读和集中。人们不再对如何使用Threads感到困惑。在这个改变之前,我们会看到人们在频道中的最后一条消息上使用Threads,即使只是向频道发送一条新消息是完全一样的。现在,在频道中回复和在 Threads 中回复之间有了真正的区别。

当然,事情仍然不完美。我们很快意识到,活动面板并不是通知人们新回复的正确方式。它很容易被忽略,但同时也让人分心。通知系统将是我们下一个挑战。

Exploration 6 — All Threads

第一次,我们在建立中央回复通知系统(即All Threads)时,不用关闭之前的实验。尽管事情并不完美,但对于我们的团队来说已经足够好,可以在正常的工作中使用。我们认为这是一个非常强烈的信号,表明我们走在正确的道路上。

All Threads 是基于Slack现有的一个功能,即所有未读信息,它可以在中央视图中显示所有用户的未读信息。该功能的成功证明了我们可以构建脱离频道上下文的视图,而且它似乎也是用于该功能的一个合理模板。

image

所有的主题让我们更容易通知用户新的回复,也让用户更容易浏览最近的回复。我们的其他设计都不允许你在关闭旧的Threads后回到旧的Threads,最终,这也是说服我们的原因,它是最好的选择。经过几天的调整,我们收到的反馈主要是关于为这个视图添加更多的功能 —— 这是一个积极的信号!为了避免让All Threads在最初推出时过于复杂的风险,我们决定将这些想法保留到未来的探索中。

Exploration 7 — Broadcasts

最后,我们需要解决的是人们担心错过的问题,回复不再出现在频道中。为此,我们做了广播 —— 让用户选择将自己的回复发布回频道的方式。

image

尽管看起来很微妙,但这是给我们试图建立的整个模型带来稳定性的最后一击。Threads 最有价值的方面是减少频道中的额外噪音,但在某些情况下,这是有问题的。对于一些人来说,之前的设计(所有回复都在频道中发布)正是他们所需要的。通过添加将回复发回频道的功能,我们允许人们灵活地使用Threads,无论哪种方式对他们都有意义。

移动端

由于Threads也同时建立在移动平台上,每一次新的探索都意味着移动版也必须调整。这对我们的移动团队来说是非常新鲜的,因为他们习惯于在大部分完成的状态下接收项目。Threads项目是一个催化剂,促成了我们今天在Slack产品团队结构方式上的许多改变,比如合并移动和核心产品团队。要想全面探讨Threads对我们移动流程的影响,需要另外写一篇(未来)博文。

Launch & Post Mortem

拥有一支出色的客户体验团队对于成功推出Threads至关重要,因为他们在使用Slack的用户和我们的产品团队之间建立了直接的沟通渠道。他们帮助我们以最好的方式推出该功能,甚至还回复了数百位多年来要求使用Threads的用户。我们最早可以追溯到2015年初。

尽管这是一条漫长的道路,但推出Threads只是真正旅程的第一步。启动总是容易的部分。从那时起,我们做了许多调整,并一直非常关注我们收到的反馈。

回顾我们所做的所有工作,我们认为我们早期的任何一个想法都可能成功,这听起来几乎是疯狂的。但每一次的设计迭代,我们都坚信这次我们有正确的解决方案,这让每一次的失败更加难以承认。这个历程是漫长的,令人兴奋的,有时也是痛苦的,但它帮助我们记住,失败是设计过程中必不可少的一部分,你只需要接受它。

我们每一次失败的探索对一小部分人来说都是成功的。在发布这么重要的功能时,不可能让所有人都满意,但在我们的努力,以及所有失败的尝试之后,我们能够以更强的信心面对批评者,对我们的解决方案。