S
Shih, Cheng-Fu6 個月前

關於useDeferredValue


useDeferredValue 透過延遲值的更新來避免繁重的計算或渲染任務阻塞用戶操作,來優化 UI 渲染性能。

在處理頻繁或高強度更新的情境中特別有用,如即時搜索功能或大型數據可視化。


1.語法

const deferredValue = useDeferredValue(value);

  • value: 你想延遲的值,可以是任何類型

以下是一個基本範例,展示了useDeferredValue 的使用方式:

    import { useState, useDeferredValue } from 'react';

    function SearchPage() {
      const [query, setQuery] = useState('');
      const deferredQuery = useDeferredValue(query);

      return (
        <div>
          <input
            type="text"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            placeholder="搜尋..."
          />
          <SearchResults query={deferredQuery} />
        </div>
      );
    }

    function SearchResults({ query }) {
      // 模擬一個較慢的元件
      return <div>搜尋結果:{query}</div>;
    }

在此範例中,deferredQuery 在快速更新期間會稍微滯後於query,這允許SearchResults 元件更新得更頻率較低,因而更加平滑。

2.運作原理

  • value 發生變化時,useDeferredValue 會返回先前的值,直到渲染閒置後再更新為新值,這可以通過減少昂貴的重新渲染頻率顯著提升性能。
  • 並且除了當前渲染(舊值),他還會安排一個後臺進行可中斷的重新渲染,如果value有新的更新,那麼React會從頭重新啟動後台渲染
  • (ex. 用戶在輸入框中輸入速度比接收延遲值的圖表重新渲染的速度快,那麼圖表只會在用戶停止輸入後重新渲染)

3.實際應用

當你有一個用於搜索大量數據的輸入欄。如果沒有useDeferredValue,每次按鍵都會觸發可能昂貴的渲染。有了useDeferredValue,渲染可以被延後,讓用戶可以持續輸入而不會感到延遲。

代碼範例

    import { useState, useDeferredValue, memo } from 'react';

    const SlowList = memo(({ text }) => {
      console.log('[人工延遲] 渲染 250 個 <SlowItem />');
      let items = [];
      for (let i = 0; i < 250; i++) {
        items.push(<SlowItem key={i} text={text} />);
      }
      return <ul className="items">{items}</ul>;
    });

    const SlowItem = ({ text }) => {
      let now = performance.now();
      while (performance.now() - now < 10) {
        // 人工長時間循環
      }
      return <li className="item">{text}</li>;
    };

    export default function App() {
      const [text, setText] = useState('');
      const deferredText = useDeferredValue(text);

      return (
        <>
          <input value={text} onChange={e => setText(e.target.value)} />
          <SlowList text={deferredText} />
        </>
      );
    }

4.與 Debouncing 和 Throttling 的區別

  • Debouncing:在指定的延遲時間後才執行操作。
  • Throttling:確保在指定的時間間隔內最多執行一次操作。
  • useDeferredValue:基於 React 的並發渲染能力延遲更新,優化 UI 響應性而不設固定延遲。

useDeferredValue執行的延遲重新渲染默認是可中斷的。這意味著,如果 React 正在重新渲染一個大型列表,但使用者進行了另一次鍵盤輸入,React 會放棄該重新渲染,先處理鍵盤輸入,然後再次開始在後台進行渲染。相比之下,防抖和節流仍會產生不順暢的體驗,因為它們是阻塞的:它們僅僅是將渲染阻塞鍵盤輸入的時間點推遲了。

5.注意事項

  • 元件設計:確保使用 useDeferredValue 的元件能夠優雅地處理過時數據。
  • 性能影響:雖然延遲更新能提高性能,但需確保延遲的渲染不會導致關鍵 UI 更新的不一致性。

6.結論

useDeferredValue 是 React 中一個強大的性能優化工具。通過延遲非緊急更新,它有助於保持 UI 的流暢性,尤其是在處理密集渲染任務的應用中。理解並有效利用useDeferredValue 可以顯著提升你的 React 應用的性能和響應速度。


其他關於hook系列文章:

關於useDeferredValue 關於useImperativeHandle 關於useSyncExternalStore 關於useTransition


圖片
圖片
圖片
圖片
圖片
圖片
(使用 Facebook 留言外掛程式 留言無法滿足本網站參加活動之資格,僅供非會員討論使用)
互動地圖
interactive taiwan map