发布于 2026-01-06 3 阅读
0

速度需要设计,或者说:你不可能取悦那些被你惹恼的用户。

速度需要设计,或者说:你不可能取悦那些被你惹恼的用户。

为了真正展现流媒体 HTML 的影响,我应该展示现有网站的设计,但要具备流媒体的速度。

演示的设计偏差

遗憾的是,我无法同时拥有现有的设计和所需的速度。这篇文章将介绍其中的一些差异。

如果我是个合格的科学家,我会记录每次偏差前后的测试结果。可惜我没有——我当时是在实际硬件和限速连接上匆忙地反复测试。如果感觉速度变慢,我就直接放弃。

如果我有什么地方说错了,我会很乐意接受有可靠来源的指正。

设计目标

说实话,我也很羡慕原生开发者。他们能以最低的资源开销,利用内置的平台支持,实现 60-120fps 的全屏动画。

但这是一个卖食品的网站:为了方便用户访问,我会毫不犹豫地牺牲用户体验。我永远无法真正赶上原生应用在交互丰富性、平台兼容性和音效方面的水平。但我可以网页的“高效便捷”方面胜过生应用。我不仅想超越我们现有的网站,也想超越我们的原生应用。

我心想,在完成这些实用、易于上手的基础部分之后,我可以添加一些装饰,迎接一些有趣的挑战。

我的业余登录页面 专业登录页面
一个基本的登录页面,包含“登录 Kroger”标题、用户名字段、密码字段、“忘记密码?”链接、“在此设备上保持登录状态”复选框以及“登录”/“创建帐户”按钮。 一片白色中出现一个加载指示器。

10秒钟后,哪个设计看起来更好?

话虽如此,我并非设计师。真正设计师或许能做出更好的权衡取舍。

字体

Kroger.com 的Nunito .woff2文件每个约 14kB,总计 55.3kB。

如果我找到一款尺寸更小的相似字体,进行大幅缩减,并应用一些更复杂的字体优化,最终大小可能可以控制在 12kB 左右。但是别忘了预算是 20kB 的。用其中的 60% 来做一款装饰性字体,实在难以令人信服。

系统字体占用主线程的时间也更少:每个 Web 字体src都会导致页面重排(它们可以一起重排,但别指望一定能做到)。通常重排效果不会太糟糕,但你知道谁最不愿牺牲性能吗?👉 就是我!👈

所以,没有网页字体

但这很容易决定:避免使用自定义字体是一种消极的做法。那么,何不尝试一些更难的呢?

产品轮播图

展示产品是电子商务最重要的任务。正因如此,我们销售的手机无法完整显示滚动产品列表才成了一个问题

由于 Poblano 屏幕尺寸的限制,产品卡片太高,一次只能看到一张。

我知道留白是设计中很重要的一部分,但这可能不是他们的意思。

这是改变的显而易见的原因,但也存在一些更微妙的缺点:

内存压力和布局成本增加

滚动窗格使用 RAM 和 VRAM 进行硬件加速滚动——但我们<body>也需要它们来进行快速滚动!

一条长长的白色条形图代表垂直滚动页面的总表面积,另外四条长条形图向右侧延伸,代表水平滚动区域。其中一条延伸得太远,以至于无法完全显示。

这是 Chrome 开发者工具图层视图中的当前首页。它只栅格化了非空白部分,但仍然计算所有区域的布局。

还记得 iOS Safari 需要手动开启加速滚动功能吗-webkit-overflow-scrolling: touch?现在你知道为什么了。

触摸屏上的滚动陷阱

这些列表占据了太多垂直空间,以至于在演示手机上变成了令人恼火的滚动陷阱,就像移动地图嵌入一样。(更糟糕的是,廉价的触摸屏在手势开始时经常会混淆滑动方向。)

重排和弹出

当滚动加载新卡片时,所有卡片的高度都会调整为与最高的卡片保持一致。即使调整幅度很小,在演示手机上,必要的布局计算仍然会出现卡顿。

小视口利用不佳

Poblano 并不是我目标屏幕尺寸最小的屏幕。我希望即使在 Apple Watch 上也能保持清晰的屏幕可读性。

相反,我这样展示产品:

演示中的产品以垂直列表的形式显示,采用网站默认的块级流程。

不,它看起来不太美观。但它的效果好得多。

您可能从上面的截图中看出几个节省空间的技巧:产品尺寸与名称对齐,利用文本的水平特性实现更紧凑的换行等等。

⌛ 我还想做其他一些事,但是时间不够了

我想利用shape-outside文字填充非矩形产品上的空白区域,这样就能放大图像。(我迫切希望在不牺牲太多信息密度的前提下,最大限度地增加屏幕上的图像像素数量。)也许哪天我会分享一下具体方法。

后来,有人告诉我滚动列表的“粘性”是一个重要的特性。我原本想通过在每个产品列表末尾的“查看更多”链接上添加该列表更多内容的缩略图来弥补这一点,但演示前时间不够。唉,人生就是如此。

box-shadow更像是bourgeois-shadow

我知道,我知道。阴影很时髦。如果运用得当,它们确实能让界面更易于理解。光影的交织正是视觉艺术的精髓所在。

但即使从严格的设计角度来看,阴影也并非全是好事:

  • 扩散/模糊阴影所需的区域需要在元素周围留出空间而这在我瞄准的小屏幕上是极其宝贵的。
  • 目前流行的阴影使用方式比较含蓄,这意味着它们永远无法成为设计的主力军。(除非你只用阴影作为设计元素,但这很糟糕。)
  • 不符合对比度要求的辅助功能,对于最需要它的人来说,其实用性值得怀疑。甚至对于大多数人来说也是如此:刺眼的阳光、疲劳的眼睛、注意力分散等等,都需要强有力的辅助功能,而不是微不足道的辅助功能。(从视觉可访问性的角度来看,我甚至不确定有多少人注意到时髦的阴影效果。)

而且,并非从严格的设计角度来看……

从历史上看,box-shadow这曾是影响游戏性能的罪魁祸首。如今可能不那么常见了,除非某些因素(例如内边距、模糊半径、透明度、阴影元素大小、屏幕分辨率、浏览器、操作系统或硬件)的组合border-radius偏离了浏览器的快速处理路径。

火焰图条,图例显示:341ms requestAnimationFrame 回调;类型:Paint。

现代建议大多告诫不要在阴影周围进行过渡或动画处理——尤其是因为在阴影下滚动也会造成影响,正如 Facebook 所了解到的那样

(没错,谷歌的 Material Design 完全专注于模糊和动画效果你见过他们为此投入了多少精力吗?)

有一些方法可以规避阴影带来的性能风险,甚至可能值得付出努力。

Kroger.com 上的优惠券,每张优惠券及其主要操作按钮均有阴影效果。

但是……唉,这些小细节似乎真的box-shadow值得。它们太隐蔽了!而且是故意的!如果我需要计划如何保护用户免受它们的侵害,那必须要有更充分的回报才行。至少拟物化设计还挺直接的。

如果一个设计效果只有视力好的年轻人才能察觉,而且还会对使用劣质或过度使用设备的人造成不可预测的负面影响……那我才不管它有多么令人愉悦。风险与我的目标相悖,而且这还是我那愚蠢的激情项目,该死的。我不信任他们,我也不需要他们。

所以,我放弃了阴影效果……但不是用那种方式。

首页推广

旋转木马 瓷砖
一个自动旋转的幻灯片,带有暂停按钮和三个点,分别指示幻灯片的数量。第一个点颜色较深,表示当前幻灯片。 3 个方块,通过“将它们并排放置”这种古老而神秘的艺术,显示与轮播图相同数量的促销活动。

想想轮播图需要哪些图块不需要的代码:

  • 滑动切换上一页/下一页与点击按钮,以及在两者之间切换的方式
  • 位置指示器
  • 暂停/播放(辅助功能必需)
  • (prefers-reduced-motion)检查和缓解
  • 方便地隐藏屏幕外幻灯片
  • 自动转发
  • 动画时序
  • 包装时将幻灯片重新定位到左侧
  • Tab ↹处理

无论这些功能的实现效率有多高,它们仍然是用户必须下载的代码。(如果用户真的喜欢轮播图,那或许值得,但是,呃……)

但演示版也没有使用图块。

将每个促销活动编码成一张大图片存在问题

因此,演示更进一步,采用了一种我暂且称之为“带状”的方法。以下是这些带状内容如何通过目标连接加载:

即使图像需要几秒钟才能加载,文字和彩色背景也会立即显示。(在大视口中,媒体查询会将它们重新排列成图块。)

无模态框、工具提示、弹出窗口等。

与本文中其他感觉像是妥协的部分不同,这部分是为了提升用户体验。喜欢应付模态框、弹出式横幅广告以及它们所有烦人的小跟班吗?反正我不喜欢。

这只是我个人的观点。我之所以放弃使用小部件而选择其他乏味的替代方案,还有一些更客观的原因:

  • 它们的 JavaScript 和 CSS 会消耗大量的性能预算。
  • 在小屏幕/触摸屏上,它们的意义就比较小了——尤其是模态框,它们几乎会占据整个页面。
  • 它们很难实现无障碍访问(尤其是模态框,被称为“网络无障碍访问的最终挑战”)。

关于最后一点,我再补充一些……即使我成功地实现了组件的无障碍访问,所需的 JavaScript 代码量也相当可观。看看一些常用模块的大小,它们分别非常适合用作工具提示、模态框和弹出窗口:

根据 Bundlephobia 的数据,JS 的成本很高
模块 精简版 .min.gz 3G 下载速度慢
@popperjs/core2.11.4 20.5 kB 7.2 kB 144毫秒
@reach/dialog0.16.2 27.3 kB 9.4 kB 188毫秒
notistack2.0.3 18.8 kB 6.4 kB 128毫秒
全部的 66.7 kB 23 kB 大约半秒!

✏️ 注意:此表不包括解析/执行时间,解析/执行时间会随着压缩后的 kB 值而增加

(是的,编写这些组件的脚本还有更高效的方法。我只是像绝大多数开发者一样,选择了看起来维护良好且流行的组件。)

最后,实现复杂的交互功能会耗费大量精力。看看 Pedro Duarte 为了制作一个易于访问的下拉菜单付出了多少努力:

下拉菜单:超过 2000 小时,6 个月,50 次审查,以及数千次提交。

来源:React 中的无头组件以及我为什么停止使用 UI 库来构建我们的设计系统

但如果这些用户界面模式令人厌烦、不易使用且成本高昂,为什么还有这么多网站使用它们呢?

  • 我认为它们更容易设计,因为它们不需要关心底层页面。
  • 我怀疑分析数据错误地报告了“用户参与度”的提升,因为它们需要比不那么突兀的设计更多的互动。即使这种互动仅仅是用户试图让该死的轮播图保持静止。
  • 有时,它们可能是解决问题的最佳方案——但一旦你拥有了该组件,就很容易将其用于其他不太合适的问题。

关于这些已知用户烦扰因素的替代方案,还有更多相关信息:

通过速度实现更好的设计

与其他章节中设计服务于速度不同,本节探讨的是页面加载速度如何促进更好的设计!

我们原有的结账流程存在展开/收缩式面板、错综复杂的错误处理机制,以及.focus()由于前两项原因导致的棘手管理问题。为了避免这些问题,我将结账流程拆分成一系列简短易用的页面:

我的结账流程页面:1. 我的购物车,2. 订单摘要,3. 联系信息,4. 感谢您选择自提!

如果你听说过“每页只显示一个内容”的布局,我就是这么做的。编码过程并不耗时,而且出乎意料地简单。

等等!还有更多!

  • 信心不足的用户会发现它们更容易使用。
  • 它们在移动设备上表现良好。
  • 它们更擅长处理错误、分支、循环和保存进度等问题。

每页只写 一件事 · 政府设计

我没有在演示中实现这些功能,但像用户帐户信息和设置这样的功能也可以很好地利用这种模式。

当我们开始对公众进行用户调研时,我们发现,即使在大屏幕上,用户对这种简单的分步式操作方式也给予了非常积极的反馈。虽然这增加了点击次数,但用户表示这种方式让整个过程感觉简单易懂——一次不需要处理太多信息。因此,我们坚持为所有用户提供更简洁的界面。

—  GOV.UK:我们在设计“选民登记”系统时学到的经验

多亏了Paint Holding,这些页面序列看起来和用起来都像单页应用程序 (SPA) 的导航一样流畅。(更多内容将在下一篇文章中介绍。)

所以呢?

就像木工需要顺着木纹雕刻一样,网页设计也需要了解什么是简单自然的,从而把精力节省下来,用在真正需要的地方。

我们目前将设计师排除在 HTML 和 CSS 之外的做法,阻碍了他们对 Web 开发中哪些事情容易、哪些事情难的直观理解。加强合作和加快反馈循环或许会有所帮助——因为我当时既要自己设计又要开发,所以我在工作中不断切换角色,尽可能地缩短了反馈周期。

但是,呃,我的设计也确实不会赢得任何选美比赛。所以别听我的,听听真正设计师的意见吧:

在下一篇文章中,我将揭露,虽然我可能是一个二十多岁、靠 React 谋生的年轻人,但我私底下却是一个十足的渐进增强爱好者


  1. 自Gruber 发表那篇文章以来,Native 技术已经有了很大的进步。现在是时候让 Web 开发者们提升自身水平了,而且不是被动追赶:“十年前我轻视 Web 应用时忽略的一点是,Web 应用并不需要以与桌面应用相同的标准来竞争。 

  2. 基于早期设计中 Poppins的结果。↩

文章来源:https://dev.to/tigt/speed-needs-design-or-you-cant-delight-users-youve-annoyed-bl6