自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

React 的 useTransition:構建高性能搜索的五萬條記錄案例研究

開發(fā) 前端
隨著應用復雜度的增加,性能可能會下降,尤其是在處理大數(shù)據(jù)集或密集用戶交互時。本文將重點介紹我們在 React 中實現(xiàn)簡單搜索過濾器時遇到的挑戰(zhàn),以及如何通過優(yōu)化組件來克服性能問題。

在構建現(xiàn)代 Web 應用時,確保流暢的用戶交互至關重要。React 憑借其強大的聲明式 UI 更新和基于組件的架構,提供了極大的靈活性。然而,隨著應用復雜度的增加,性能可能會下降,尤其是在處理大數(shù)據(jù)集或密集用戶交互時。本文將重點介紹我們在 React 中實現(xiàn)簡單搜索過濾器時遇到的挑戰(zhàn),以及如何通過優(yōu)化組件來克服性能問題。

問題:與大數(shù)據(jù)集的用戶交互

想象一個應用,它顯示一個龐大的用戶列表,用戶可以通過在搜索框中輸入來過濾該列表。乍一看,這似乎是一個簡單的任務,但隨著用戶數(shù)量的增加,即使是很小的低效也會導致嚴重的性能問題。我們最初構建了一個搜索過濾器組件,允許用戶通過姓名或電子郵件過濾 5,000 名用戶的列表。交互包括在輸入字段中輸入,并在用戶輸入時動態(tài)過濾列表。然而,性能很快就變得有問題。

原始方法

這是我們組件的第一個版本:

import React, { useState, useTransition } from"react";

// ?? 假用戶生成器
constgenerateUsers = (count: number) => {
const names = ["Alice", "Bob", "Charlie", "David", "Eve", "Frank", "Grace", "Helen"];
returnArray.from({ length: count }, (_, i) => ({
    id: i,
    name: `${names[i % names.length]} ${i}`,
    email: `user${i}@example.com`,
  }));
};

const usersData = generateUsers(5000);

exportdefaultfunctionMassiveSearchFilter() {
const [query, setQuery] = useState("");
const [filteredUsers, setFilteredUsers] = useState(usersData);
const [isPending, startTransition] = useTransition();

consthandleSearch = (e: { target: { value: any; }; }) => {
    const value = e.target.value;
    setQuery(value);

    startTransition(() => {
      const lower = value.toLowerCase();
      const filtered = usersData.filter(
        (user) =>
          user.name.toLowerCase().includes(lower) ||
          user.email.toLowerCase().includes(lower)
      );
      setFilteredUsers(filtered);
    });
  };

consthighlight = (text: string, query: string) => {
    if (!query) return text;
    const index = text.toLowerCase().indexOf(query.toLowerCase());
    if (index === -1) return text;
    return (
      <>
        {text.slice(0, index)}
        <mark className="bg-pink-200 text-black">
          {text.slice(index, index + query.length)}
        </mark>
        {text.slice(index + query.length)}
      </>
    );
  };

return (
    <div className="min-h-screen bg-gray-100 p-6 font-sans">
      <div className="max-w-3xl mx-auto bg-white p-6 rounded-2xl border-2 border-pink-200 shadow-md">
        <h1 className="text-2xl font-bold text-pink-600 mb-4">
          ???? 大規(guī)模搜索過濾器(5,000 用戶)
        </h1>

        <input
          type="text"
          value={query}
          onChange={handleSearch}
          placeholder="搜索姓名或電子郵件..."
          className="w-full p-3 mb-4 border-2 border-pink-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-pink-400"
        />

        {isPending && (
          <div className="text-pink-500 italic mb-2 text-sm animate-pulse">
            ?? 加載結果中...
          </div>
        )}

        <div className="max-h-[500px] overflow-y-auto divide-y divide-pink-100 border-t border-pink-100">
          {filteredUsers.map((user) => (
            <div
              key={user.id}
              className="p-3 hover:bg-pink-50 transition-colors duration-150"
            >
              <p className="font-medium text-gray-800 text-base">
                {highlight(user.name, query)}
              </p>
              <p className="text-sm text-gray-500">
                {highlight(user.email, query)}
              </p>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

面臨的挑戰(zhàn)

起初,一切似乎都很順利。搜索速度很快,結果幾乎瞬間出現(xiàn)。然而,當我們開始使用更大的數(shù)據(jù)集(例如 5,000 多名用戶)進行測試時,以下問題很快就變得明顯:

  1. 性能瓶頸:在搜索字段中快速輸入時,組件會顯著變慢。React 會在每次按鍵時重新渲染整個 5,000 名用戶的列表,導致 UI 更新延遲。
  2. UI 凍結:由于搜索過濾器直接與輸入字段和用戶交互綁定,快速輸入或刪除文本會導致 UI 凍結,因為 React 被過濾和重新渲染數(shù)千個 DOM 節(jié)點的任務壓垮了。
  3. 過度依賴過濾:搜索輸入中的每次更改都會觸發(fā)對整個列表的過濾,即使用戶仍在輸入,這也是低效的。

優(yōu)化過程

在識別出問題后,我們應用了幾種技術來提高性能和用戶體驗:

步驟 1:使用 react-window 進行虛擬化

渲染 5,000 多個項目是虛擬化的經典案例。我們決定使用 react-window,它允許 React 僅渲染視口中可見的項目。這意味著即使在大數(shù)據(jù)集的情況下,我們也不需要渲染整個列表,從而大大減少了瀏覽器的負載。

步驟 2:過濾結果的記憶化

通過使用 useMemo 鉤子,我們根據(jù)查詢對過濾結果進行了記憶化。這確保了過濾計算僅在查詢更改時發(fā)生,而不是在每次渲染時發(fā)生。

步驟 3:使用 startTransition 實現(xiàn)平滑的 UI 更新

useTransition 鉤子允許我們優(yōu)先更新輸入字段,同時推遲過濾計算。這確保了 UI 在應用執(zhí)行更昂貴的過濾任務時仍保持響應。

優(yōu)化后的組件

以下是經過這些更改后的優(yōu)化版本組件:

import React, { useState, useMemo, useTransition } from"react";
import { FixedSizeListasList } from"react-window";

constgenerateUsers = (count: number) => {
const names = ["Alice", "Bob", "Charlie", "David", "Eve", "Frank", "Grace", "Helen"];
returnArray.from({ length: count }, (_, i) => ({
    id: i,
    name: `${names[i % names.length]} ${i}`,
    email: `user${i}@example.com`,
  }));
};

const usersData = generateUsers(5000);

exportdefaultfunctionMassiveSearchFilter() {
const [query, setQuery] = useState("");
const [isPending, startTransition] = useTransition();

const filteredUsers = useMemo(() => {
    const lower = query.toLowerCase();
    return usersData.filter(
      (user) =>
        user.name.toLowerCase().includes(lower) ||
        user.email.toLowerCase().includes(lower)
    );
  }, [query]);

consthandleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    startTransition(() =>setQuery(value));
  };

consthighlight = (text: string, query: string) => {
    if (!query) return text;
    const index = text.toLowerCase().indexOf(query.toLowerCase());
    if (index === -1) return text;
    return (
      <>
        {text.slice(0, index)}
        <mark className="bg-pink-200 text-black">
          {text.slice(index, index + query.length)}
        </mark>
        {text.slice(index + query.length)}
      </>
    );
  };

constRow = ({ index, style }: { index: number; style: React.CSSProperties }) => {
    const user = filteredUsers[index];
    return (
      <div
        style={style}
        key={user.id}
        className="p-3 border-b border-pink-100 hover:bg-pink-50"
      >
        <p className="font-medium text-gray-800 text-base">
          {highlight(user.name, query)}
        </p>
        <p className="text-sm text-gray-500">{highlight(user.email, query)}</p>
      </div>
    );
  };

return (
    <div className="min-h-screen bg-gray-100 p-6 font-sans">
      <div className="max-w-3xl mx-auto bg-white p-6 rounded-2xl border-2 border-pink-200 shadow-md">
        <h1 className="text-2xl font-bold text-pink-600 mb-4">
          ???? 大規(guī)模搜索過濾器(虛擬化)
        </h1>

        <input
          type="text"
          value={query}
          onChange={handleSearch}
          placeholder="搜索姓名或電子郵件..."
          className="w-full p-3 mb-4 border-2 border-pink-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-pink-400"
        />

        {isPending && (
          <div className="text-pink-500 italic mb-2 text-sm animate-pulse">
            ?? 過濾中...
          </div>
        )}

        {filteredUsers.length === 0 ? (
          <div className="p-4 text-gray-500 italic text-center">未找到用戶。</div>
        ) : (
          <List
            height={500}
            itemCount={filteredUsers.length}
            itemSize={70}
            width="100%"
            className="border-t border-pink-100"
          >
            {Row}
          </List>
        )}
      </div>
    </div>
  );
}

結論

通過應用虛擬化、記憶化和UI 優(yōu)先級策略,我們能夠顯著提高搜索過濾器組件的性能。用戶交互現(xiàn)在變得流暢且響應迅速,即使有數(shù)千個項目需要過濾。

這一經驗凸顯了在處理大數(shù)據(jù)集或復雜用戶交互時優(yōu)化性能的重要性。React 的內置鉤子如 useMemo、useTransition 以及第三方庫如 react-window 可以極大地影響應用的用戶體驗,使其感覺更加流暢和高效。

代碼參考: https://github.com/paghar/react19-next15-trickysample

原文地址: https://dev.to/fpaghar/mastering-usetransition-in-react-building-a-high-performance-search-for-50k-record-case-study-1bdn作者: Fatemeh Paghar

責任編輯:武曉燕 來源: 前端小石匠
相關推薦

2024-06-14 07:47:37

2023-09-04 08:32:43

web開發(fā)圖像

2020-02-26 14:50:41

React搜索前端

2020-06-05 07:20:41

測試自動化環(huán)境

2011-12-15 13:28:57

2022-04-28 20:12:44

二分法搜索算法

2022-04-12 16:39:55

數(shù)據(jù)泄露網絡攻擊

2011-08-29 16:05:07

高性能SQL語句SQL Server

2024-12-02 14:28:17

JavaScriptWeb開發(fā)

2019-06-12 15:20:25

Redis高性能線程

2023-12-01 07:06:14

Go命令行性能

2023-12-14 08:01:08

事件管理器Go

2023-10-26 08:35:53

2019-03-14 15:38:19

ReactJavascript前端

2022-12-09 08:40:56

高性能內存隊列

2011-10-21 14:20:59

高性能計算HPC虛擬化

2011-10-25 13:13:35

HPC高性能計算Platform

2023-08-11 08:34:40

開發(fā)工具

2016-05-20 14:20:31

ASP.NET建議

2023-09-04 14:52:48

點贊
收藏

51CTO技術棧公眾號