【体验优化】IOS的这个加载优化小技巧真的很 nice

694 阅读4分钟

在前端开发的世界里,用户体验(UX)是永远无法被忽视的一个方面,尤其是在web应用中,加载时的流畅度、响应性直接决定了用户是否愿意继续使用你的应用。今天,想和大家分享一个在iOS系统设置中使用的加载小技巧——延迟显示加载动画,这个技巧可以让你的页面加载更加平滑,避免因为请求过快而给用户带来不好的页面闪烁体验。

背景

在日常的开发中,常见的做法是在发起网络请求时,通常会显示一个 loading 动画,表示数据正在加载中。但问题在于,假如数据加载非常快(比如几毫秒),那么整个页面可能会突然闪烁了一下,让用户感到困惑。而咱们又不能直接去除该 loding 动画,否则在慢速请求的情况,用户会以为页面没有反应

实现思路

如何解决这个问题呢?ios的系统设置中给出的答案是:延迟显示加载动画。那么咱们就来简单的实现一下该功能吧。

核心思路

  1. 如果请求时间非常短(比如小于 200ms),我们不显示 loading 动画。
  2. 如果请求时间较长(超过 200ms),我们才显示 loading 动画。而在显示 loading 动画后,需要计算请求的时长,确保 loading 会显示500ms才消失(确保不会有瞬间闪烁的问题)

简单来说,如果数据响应的速度非常快,我们认为用户几乎没有等待时间,不需要显示 loading;如果请求时间较长,那么我们就需要给用户一个正在加载的提示,并且这个加载的动画需要显示一定的时长,避免让他们觉得应用卡顿无响应或者出现闪烁之类的不好体验。

时间选择

200ms500ms这 两个时间值并非严格的标准,而是根据用户的视觉感知交互体验来设置的。一般来说,200ms 是用户能够感知到交互延迟的一个临界点,而 500ms是用户感觉到是否有闪烁临界点,这个值也可以根据具体需求进行调整,但 200ms500ms作为一个基准值,能够满足大多数场景下的需求。

效果对比

可以发现,延迟显示加载动画在低延迟时,不会有明显的loading或者闪烁的问题

而在高延迟的场景下,延迟加载动画的执行速度会稍慢一些(200ms后才显示),但也基本是在用户的无感知的情况下。

代码

import React, { useState, useEffect } from 'react';
import { Button, Spin, Select } from 'antd';
import "./index.less"

const DEFAULT_DURATION = 200;
const DEFAULT_LOADING_SHOW_TIME = 500;

export default function IosLoading() {
  const [isLoading, setIsLoading] = useState(false);
  const [duration, setDuration] = useState(50);
  const [data, setData] = useState(null);

  const mockRequest = () => {
    const start = Date.now();
    return new Promise((resolve) => {
      setTimeout(
        () =>
          resolve({
            code: 200,
            message: 'success',
            duration: Date.now() - start,
          }),
        duration,
      );
    });
  };

  // 请求
  const fetchData = async () => {
    const start = Date.now();
    setData(null);

    // 在请求开始后xxx ms开始显示 loading
    const loadingTimer = setTimeout(() => {
      setIsLoading(true);
    }, DEFAULT_DURATION);

    mockRequest().then((res) => {
      const end = Date.now();
      const _duration = end - start;
      if (_duration < DEFAULT_DURATION) {
        clearTimeout(loadingTimer);
        setIsLoading(false);
        setData(res);
      } else {
        setTimeout(() => {
          setData(res);
          setIsLoading(false);
        }, DEFAULT_LOADING_SHOW_TIME + DEFAULT_DURATION - _duration);
      }
    });
  };

  const defaultfetchData = async () => {
    setIsLoading(true);
    mockRequest().then((res) => {
      setIsLoading(false);
      setData(res);
    });
  }

  return (
    <div className='ios-loading'>
      <div>
        <Select
          style={{ marginBottom: 12, width: 120 }}
          value={duration}
          onChange={(value) => {
            setDuration(value);
          }}
          options={[
            { label: '50ms', value: 50 },
            { label: '100ms', value: 100 },
            { label: '150ms', value: 150 },
            { label: '200ms', value: 200 },
            { label: '500ms', value: 500 },
            { label: '1000ms', value: 1000 },
          ]}
        />
      </div>
      <div>
        <Button type='primary' onClick={fetchData}>
          延时动画请求
        </Button>
        <Button onClick={defaultfetchData}>
          默认请求
        </Button>
      </div>

      {isLoading && <div className='loading'><Spin size='large' /></div>}
      <div>请求耗时:{data?.duration}ms</div>
    </div>
  );
}

源码和 demo 链接

github:github.com/sulgweb/dem…

demo 链接:demo.sulg.top/

小结

尽管我们常常会默认展示 loading 动画,但其实这并不是唯一的选择。在某些情况下,通过延迟显示加载动画能够大大提升用户体验,避免了因网络请求快速导致的不必要加载展示。通过这种方式,我们让加载动画成为真正需要时才出现的用户友好提示,而不是一个“冗余”的存在。

希望这个小技巧能帮助你提升应用的加载体验,减少因加载过快给用户带来不好的体验。毕竟,良好的用户体验往往是在细节处做得好,才会让用户无感知地享受到应用的流畅高效