在web中,设计加载态经常被忽略或者事后才考虑。web性能不仅是开发人员的职责,在慢速网络上给用户创造良好的体验也是一个设计挑战。
开发人员需要注意压缩、缓存,而设计人员就需要考虑系统加载过程中或者离线时的UI表现和行为。
速度错觉
随着我们对移动体验的期望发生变化,我们对性能的理解也随之改变。人们希望,无论他们的网络覆盖如何,web应用都能像原生apps一样响应快速。
感知性能是用来衡量一个东西让用户感觉有多快。一个观念是:如果用户能知道系统正在发生什么,且能提前预测内容,那么用户就会更有耐心,且会觉得这个系统较快。合理利用用户期望,并告知用户很重要。
对一个web应用而言,这个概念也许包含文本、图片或其他元素构成的轮廓展示——也就是skeleton screens。你可以很轻易的找到它,像Facebook, Google, Slack等公司都在使用。
Holy moly to you too, Slack.
Facebook’s Skeleton
举个栗子
假设你正在构建一个web应用。它是一个旅游攻略类的应用,用户可以分享旅行,推荐地方等,所以你的主要页面内容可能会像下面这样:
你可以把它简化为基本的视觉形状,即UI组件的轮廓。
无论人们什么时候从服务器请求新内容,你都可以立刻开始显示页面轮廓,而数据在后台加载。一旦内容准备好了,用实际的内容替换占位轮廓即可。这过程可以用原生的JavaScript或者现成的库如:React实现。
你可以用一张图片来显示这个页面轮廓,但是这会引入额外的请求和数据开销。我们已经在加载内容了,却还要去等待另一张图片先出现,这并不是一个好方法。而且,它并不是响应式的,如果我们决定调整某些内容的样式,我们就必须把改动同步到skeleton image,这样两者才能匹配上。oh,好无聊~~
一个更好的解决方法是只用CSS实现整个页面轮廓。没有额外的请求,最小的开销,甚至不需要任何额外的标记。而且,我们可以用一种使后期改变设计更容易的方式来构建它。
用CSS绘制页面轮廓
首先,我们需要绘制基本形状来组成页面轮廓。我们可以通过给background-image
属性添加不同的渐变来实现。线性渐变(linear gradients )默认从上到下,通过不同的颜色结束过渡效果。如果我们只设定一种结束颜色,其余部分设成透明(transparent),我们就可以绘制形状了。
请记住:多个background-images会相互叠加,所以顺序很重要。后定义的在最下面,先定义的在最上面。
这些形状延伸到了整个空间,就像普通的块状(block)元素。如果我们想控制它们的大小,就必须定义精确的尺寸。可以在background-size
中设置每一层的宽高,但要和background-image
中的顺序保持一致。
最后一步是设置元素的位置background-position。表现和position:absolute一样,属性值分别相当于left,top。例如像真实的页面内容那样,我们给头像和标题模拟24px的padding值:
使用自定义属性实现(Break it up with Custom Properties)
上面的例子在简单的页面中很好用,但是如果页面复杂一些,CSS很快就会变得很混乱,难以阅读。如果其他开发者接手代码,他们会完全不知道那些神奇的数据从哪来的,代码也很难维护下去。
值得庆幸的是,现在我们可以使用自定义的CSS属性以一种更简洁、对开发者更友好,甚至将不同值之间的关系都考虑在内的方式去写页面轮廓。
这样不仅易于阅读,还更有利于后期样式修改。而且,我们可以用变量(像:--avatar-size
--card-padding
等)去定义真正的页面样式,这样,轮廓和真正页面样式便能一直同步。
现在添加媒体查询以在不同的断点调整skeleton的某部分也很简单:
注意:浏览器对自定义属性的兼容性虽不足100%,但也不错。基本所有现代浏览器都支持,IE/Edge部分支持。对于上文的例子,通过sass变量添加备用属性即可。
添加动画(Add Animation)
进一步优化,我们给页面轮廓添加动画,让它更像一个加载进度指示器。我们需要做的只是在最上层添加一个新的渐变,然后用@keyframes
将它的position动起来。
下面是一个完整的页面轮廓的例子:
live demo
说明:可以使用空选择器(:empty)和伪元素绘制页面轮廓,因为它只适应于空元素,一旦页面真正内容填充完成,轮廓就会自动消失。
更多性能相关设计
更多感知性能相关的设计,请查看这些链接:
Designer VS. Developer #8: Designing for Great Performance
Vince Speelman: The Nine States of Design
Harry Roberts: Improving Perceived Performance with Multiple Background Images
Sitepoint: A Designer’s Guide to Perceived Performance
译者注
查了下国内在用的网站,领英,简书首页有采用这个方案,简书实现方案是:写2套样式,通过js判断loading状态,动态切换样式class。可能考虑到兼容性的问题,简书用的是简单的css样式加@keyframes动画,并没有用这种自定义的css属性。
国外有Facebook iOS版、Medium、WordPress App、Slack等产品采用。
PS:把网速调慢之后看的更清楚
适用于布局排版固定的内容区域
Skeleton Screen所展现的是内容的大概轮廓,如果内容布局和排版不是固定的,那么轮廓和内容布局的巨大差异,不仅不能给用户顺畅和期待感,反倒会造成落差。因此Skeleton Screen适用于布局排版固定的内容区域,例如列表、文章、个人信息。注意:如果内容区域有空页面的情况,也不建议使用Skeleton Screen。
建议配合其他加载技术一起使用
用户的网络环境是复杂的,如果加载持续时间很久,单凭Skeleton Screen起不到流畅过渡的效果,建议配合懒加载(先文字后图片)、逐条加载、预加载等技术,以达到更出色的体验。
Ps:第一次尝试翻译外文,若有不对的地方,欢迎指出~~