原文:https://daverupert.com/2024/02/ui-states/
作者:Dave Rupert
译者:ChatGPT 4 Turbo
编者注:想不到居然有这么多 state。
“UI 是状态的函数” 在前端世界中相当流行。在上下文中(双关语),这通常是指应用程序或组件的状态。我想进一步探索所有可能影响 UI 层的状态……
第一方应用状态
每个应用程序,无论是待办事项列表、购物车还是一些极其复杂的应用程序,都会有一些状态。状态并不是统一的,通常存在于不同的层次上。我们将从顶部开始向下钻研……
全局状态
通常在应用程序级别发生的数据存储和功能开关。
- Stores – 用于存储数据的不同位置
- 应用存储 – Redux、Vuex、Mobx、Signals
- 浏览器存储 – localStorage、sessionStorage、cookies、IndexedDB
- Data – 各种类型的全局数据
- 访问控制数据 – 认证令牌、已付费/未付费、地理定位、年龄、已验证、会员等
- 用户数据 – 名称、图标等
- 集合 – 例如帖子列表
- 会话数据
- … 等
页面/组件状态
Vince Speelman 的精彩著作《设计的九种状态》很好地总结了一个页面或组件可能存在的所有状态。
- Nothing – 一个空元素
- Loading – 正在发生一个
fetch
- None – 没有返回任何项目
- One – 单个项目返回
- Some – 一些物品被返回
- Too Many – 返回太多项,需要分页(或类似功能)
- Incorrect – 发生了一个错误
- Correct – 发生了成功事件
- Done – 操作结束
Vince 的清单对我来说是完美的,这么多年后仍然相关,我会再加两项。
- 自定义状态 – 与您的应用程序相关的任何定制或自定义状态
- 实时多玩家事件消息 – 想象聊天应用或实时股票行情不断更新的状态。存储在组件级别或投入全局状态。
- 滚动位置 – 页面和组件经常需要知道它们是否已滚动进入或离开视口。
在我的经验中,页面和每个组件都会包含这些状态的某种混合,并且会对全局状态变化做出响应。
元素状态
单个元素可以(并且将会)拥有它们自己的状态。在这一层面上,HTML、CSS 和 ARIA 的特性开始显现出来。
- 光标状态
default, pointer, wait, text, move, grab, crosshair, zoom-in, zoom-out
, … 等- 自定义光标
- IntersectionObserverEntry
- isIntersecting = true, false
- 层叠上下文
z-index
- Layer
- Root
::backdrop
- Top
- 属性状态 – 在 HTML 中反映的状态
- Visibility =
hidden, visible
- Language =
dir, lang
- Functionaltiy =
contenteditable, draggable, invoketarget
- Display =
inert, open, popover
- Loading =
lazy, eager
- Visibility =
- Pseudo-class states – 在 CSS 中反映的状态
- Action =
:hover, :active, :focus, :focus-visible, :focus-within
- Input =
:autofill, :checked, :disabled, :valid, :invalid, :user-valid, :user-invalid, :required
, … 等 - Display =
:fullscreen, :modal, :picture-in-picture
- Language =
:dir(), :lang()
- Location =
:link, :visited, :target
, … - Resource =
:playing, :paused
资源 =:playing, :paused
- CustomStateSet = 自定义状态集合用于网页组件
- … etc
- Action =
- ARIA states – user-facing states reflected in ARIA
aria-current
aria-expanded
aria-pressed
aria-hidden
- … etc
第二方用户(或设备)状态
应用程序的用户及其设备、外围设备和浏览器在最终应用程序的渲染方式上有很大的发言权。这是有意为之,并内置于网络的基础之中。
语言和本地化
惊喜!并不是所有用户都住在 US-West-2。
- 文本方向 =
ltr, rtl
- Writing mode =
horizontal-tb, vertical-lr, vertical-rl
- 服务器/CDN 的距离(延迟)
- 自动翻译
- 词语很长(例如德语)
- 词语很短(例如:中文)
设备限制
用户的设备具有很多变化和定制化,可能是渲染到玻璃时你最大的未知瓶颈。
- 网络连接 = 光纤、电缆、无线网络、5G、4G、3G、“伪网络”
- Viewport =
height, width, initial-scale, horizontal-viewport-segments, vertical-viewport-segments, viewport-segment-width, viewport-segment-height
, … - 环境常量 =
safe-area-inset-*
,titlebar-area-*
,keyboard-inset-*
(例如,iPhone 刘海,圆角,已安装应用) - 像素密度 = 1x、2x(视网膜)、3x、……等
- 低功耗模式
- 屏幕亮度
- CPU 速度
- GPU/dGPU
- L1/L2/L3 缓存
- CPU/GPU/内存争用(例如,其他应用程序打开)
- 色域支持 = Rec2020、P3、sRGB……等
- 键盘 = 嵌入式,外接式,T9,虚拟屏幕键盘,触控条,……等
- XR support =
inline, immersive-vr, immersive-ar
模态
用户在与设备交互时并不统一,他们可能会同时使用一种或多种输入和输出方式。
- 输入
- 鼠标 = 单键、双键、滚轮、轨迹球、触摸板、高/低 DPI
- 键盘 = 100%,60%,小键盘,QWERTY,Colemak,人体工学,分体式,机械式,……等
- 触摸/轻点 = 粗指针,无悬停
- 触控笔 = 细尖端,悬停,压感
- 手势 = 捏合缩放,两/三/四指滑动
- 运动 = 加速度,摇晃撤销,碰撞,等等
- 方向 = 横向、纵向、alpha/beta/gamma(分别为 360º/180º/90º 旋转)
- 语音识别 = Dragon NaturallySpeaking,语音助手
- 开关 = 按钮,轻吸,轻吹
- 眼动追踪
- 游戏手柄
- XR = 3 DOF, 6 DOF
- 输出
- 屏幕
- 文本转语音
- 屏幕阅读器
- 盲文
- 屏幕放大镜
- 振动
- RSS?
Browser states 浏览器状态
最后,用户的浏览器选择和首选插件在很大程度上决定了他们如何体验(或希望体验)你的 UI,而你的应用程序可以对这些偏好做出响应。
- 用户偏好
- prefers-color-scheme = light, dark, forced-colors
- prefers-reduced-motion = reduce, no-preference
- prefers-reduced-transparency = reduce, no-preference
- user zoom = 100% to 400%
- text size = small to x-large
- 功能特性
- 浏览器版本 = 最新版本,最后2个版本,更旧版本
- 特性检测 =
@support
或 polyfills - 色域支持 = Rec2020、P3、sRGB……等
- 浏览器缓存命中
- Service worker 命中
- 显示模式 = 全屏 | 独立 | 极简界面 | 浏览器
beforeinstallprompt
- 打印模式
- 阅读模式
- JavaScript 禁用 = 是的,我确实认识这么做的人。
- Sleeping tabs
- 权限
- Camera = true, false
- Microphone = true, false
- Geolocation = allowed, not allowed, only while using the app
- Notifications = true, false
- File access = true, false
- 插件
- Ad blockers – UBlock, Safari ITP, Ghostery, … 等
- 自定义插件 / 提升
用户状态
到目前为止,我们讨论了技术,现在让我们考虑交易另一端的实际人类。用户的身体或心理状态影响他们享受你的体验的认知或实际带宽。
- 遇到紧急情况/危机
- 认知障碍
- 永久性或临时性残疾
- “Out of spoons”
- 内部或外部
- 在飞机或火车上
- 在城市里或者在树林中
第三方服务状态
第三方对 UI 的用户体验有着超乎寻常的影响。
可用性/状态
其他服务器的状态/可用性/正常运行时间是 UI 最大的故障面。
- 服务器硬件状态 = 在线,离线,部分可用
- 数据库状态 = 在线,离线,事务锁定
- API 状态 = 在线,离线,部分可用
- Web 字体服务 = 在线、离线、部分可用
- DNS 状态 = 可能需要最多 72 小时才能解析
- 包依赖关系 = 正常工作,损坏,恶意注入,抗议软件,等等
- 资产交付和缓存状态
- Cloudflare
- S3
脚本注入
第三方脚本注入是 UI 性能下降的最大原因。有些服务甚至接管了应用程序的用户体验。这通常是你无法控制的。
- 分析/追踪服务
- 用户会话录制服务
- A/B 测试注入
- 指导性覆层
- 辅助功能覆盖层
- 第三方认证(OAuth)服务
- 验证码/验证服务
你还没真正体验过生活,直到这些未经检查的服务之一拖垮了一个应用程序。
UI 不仅仅是状态……
我确信我忘记了整个状态类别。我甚至还没有涉及数百个 CSS 属性以及数千个值及其潜在的冲突。我没有谈论设计表单控件的复杂性或者使用所需的 ARIA 属性组合构建下拉菜单。我没有触及放置页面上图片所需的决策矩阵。这也没有涉及按正确顺序设置 head
中所有恰当的标签。这也没有讨论用于 SEO 的微格式或者你需要正确设置 UI 以发送分析数据的所有代码。
在结束时,要雇佣擅长 UI 的人。