• js防抖动功能
  • 发布于 1周前
  • 63 热度
    0 评论
学习这个强大的 JS 特性,可以极大地提高用户体验,阻止用户放弃你的应用。并大大节省成本。

他们会讨厌你的应用程序

没有它,他们会因为糟糕的用户体验而感到恼火,永远不会回来。

示例:想象一下,已经创建了一个出色的 AI 写作助手,为编写引人入胜的故事提供有用的建议:


已经在 handleChange 中为请求设置好了API:
export function AssistantUI() {
  const [suggestions, setSuggestions] = useState('');
  const [loading, setLoading] = useState(false);

  const handleChange = async (event: any) => {
    const value = event.target.value;
    setLoading(true);
    const res = await fetch(
      'https://api.writer.example.com/suggestions',
      {
        method: 'POST',
        body: JSON.stringify({ text: value }),
      }
    );
    const json = await res.json();
    setSuggestions(json.suggestions);
    setLoading(false);
  };

  return (
    <div className="flex flex-col justify-center flex-wrap content-start">
      <textarea
        onChange={handleChange}
        className="mt-2 mb-4"
        cols={40}
        rows={10}
      />
      {/* ... */}
    </div>
  );
}
但不幸的是,存在一个严重的问题 - 你能发现吗?

我刚开始写作,你的 AI 立刻就在告诉我关于拼写错误的胡说八道!我的呼吸空间在哪里?你不能至少让我停止打字吗?哦不,我完了——你毁了我的一天,我永远不会回来😠。但幸运的是,那只是你在另一个现实中的样子——真正的你已经知道这样的用户体验最好是令人烦恼,最糟糕的是令人愤怒。

这就是为什么你知道这是编写 handleChange 的更好方式:
export function AssistantUI() {
  const [suggestions, setSuggestions] = useState('');
  const [loading, setLoading] = useState(false);

  const timeout = useRef<NodeJS.Timeout | null>(null);
  const handleChange = async (event: any) => {
    const value = event.target.value;
    setLoading(true);

     // 重新启动延迟
    clearTimeout(timeout.current!);

   //  在获取数据前延迟1秒
    timeout.current = setTimeout(async () => {
      const res = await fetch(
        'https://api.writer.example.com/suggestion',
        {
          method: 'POST',
          body: JSON.stringify({ text: value }),
        }
      );
      const json = await res.json();
      setSuggestions(json.suggestions);
      setLoading(false);
    }, 1000);
  };

  return (
    <div className="flex flex-col justify-center flex-wrap content-start">
      <textarea
        onChange={handleChange}
        className="mt-2 mb-4"
        cols={40}
        rows={10}
      />
      {/* ... */}
    </div>
  );
}
现在 AI 在给出建议前会等待 1 秒!

现在每个人都爱上了你的应用程序 - 即使我们尝试,也无法停止使用它。在编程中,我们称这种技术为防抖。它无处不在..
Google 搜索:无论何时搜索,你都在体验防抖动的实际应用。

注意输入和自动完成更新之间的延迟。这不是延迟,而是防抖。
对话:当我们在辩论,你让我先说完我的观点再回应,你就是在防抖。
你没有打断我并开始尖叫——你通过不断设定一个潜意识的超时,确保我最终停止说话:
let silenceTimeout;
let silenceDelay = 1000;
// 堆代码 duidaima.com
function debounceReplyToOpponent() {
  clearTimeout(silenceTimeout);
  silenceTimeout = setTimeout(() => {
    reply('Your fallacious premises have no basis in reality');
  }, silenceDelay);
}
你损失了数千美元
用户不是唯一负载过重的 —— 服务器正在呼救。
在防抖动之前:
1000 个用户每秒打字 10 次 = 10 x 60 x 1000 = 600,000 次请求每分钟!
这个负载并不是云计算的功能问题,但是成本呢?
尤其是因为你可能正在使用像 OpenAI 或 GCP Vertex 这样的昂贵的 AI 服务。
打字频率不再重要 - 如果他们每分钟暂停打字 10 次,那就没关系
10 x 1000 = 10,000 次请求每分钟!请求和成本减少了 98.3%!
之前每天花费 1000 美元,但现在的花费少于 170 美元(!)
你过去花一天的时间,现在需要花一周的时间。这要归功于防抖。

但是你可以做得更好
好吧,但那仍然相当于每月 5000 美元 - 我们能做得更好吗?用户中有 90%是免费的,我们需要将他们的使用量保持在最低限度。幸运的是,你非常聪明,所以你很快就想出了这个:
const timeout = useRef<NodeJS.Timeout | null>(null);
const ignoring = useRef<boolean>(false);
const handleChange = async (event: any) => {
  if (plan === 'free') {
    // 仍在忽略,所以返回
    if (ignoring.current) return;

    // 开始忽略 20 秒
    ignoring.current = true;
    setTimeout(() => {
      ignoring.current = false;
    }, 20 * 1000);
  }

  debounce();
  const value = event.target.value;
  setLoading(true);
  const res = await fetch(
    'https://api.writer.example.com/suggestion',
    {
      method: 'POST',
      body: JSON.stringify({ text: value }),
    }
  );
  const json = await res.json();
  setSuggestions(json.suggestions);
  setLoading(false);
};
在获取他们的最后一个建议后,你将忽略免费用户 20 秒。
所以他们每分钟只有 3 个建议。
900 个免费用户,100 个付费用户。
900 x 3 + 100 x 10 = 3,700 次请求每分钟 - 从5100降至1,900。

一箭双雕:
1.63%的节省

2.激励免费用户升级以获得无限建议。


这是我们称之为节流的另一种技术。并且它会出现在你有周期性限制访问某物的任何地方:
GPT-4o 模型:自 2024 年 5 月 13 日起,仅允许 Plus 用户每 3 小时发送 80 条消息。
吃东西:你一次只能吞下那么多食物
我们早些时候辩论的回顾:
防抖:你等我说完再回应,反之亦然。
节流阀:我们每次最多只有 5 分钟的时间来交谈。
有了这个强大的组合,原本只持续一天的现在可以持续 3 周。

60 万个请求变成了 3700 个,每个人都喜欢你的应用。
用户评论