前端

React useTransition 深入解析

基本概念

useTransition 是一个帮助你在不阻塞 UI 的情况下更新状态的 React Hook,在React 18 中引入,它允许我们将某些更新标记为非紧急的,从而提高应用程序的响应性。

React 文档

基本用法

import { useTransition } from 'react'; function MyComponent() { /* isPending: 表示过渡是否正在进行中。 startTransition: 包装我们想要标记为非紧急的更新. */ const [isPending, startTransition] = useTransition(); const handleClick = () => { startTransition(() => { // 在这里进行状态更新 }); }; return ( // 组件渲染逻辑 ); }

工作原理

  1. 当我们调用 startTransition 并传入一个回调函数时,React 会将该回调函数中的所有状态更新标记为非紧急。
  2. React 会先处理所有其他紧急的更新,然后再处理这些非紧急更新。
  3. 在过渡期间,React 可能会多次中断和恢复渲染,以确保不会阻塞主线程。

关键点

  1. 立即执行:传入的函数会在主线程上立即执行,这与常规函数调用并没有区别。它不会异步或推迟执行,也不会切换到其他线程上去执行。
  2. 调度状态更新:startTransition 内部函数执行过程中触发的状态更新,如 setState,该状态更新会被标记为 transition。
  3. 只影响 React 更新的优先级

拓展: requestIdleCallback 和 web worker

useTransition 和 requestIdleCallback 都是用于优化性能的方法,但它们在工作方式和使用场景上有一些重要的区别。

  • startTransition 解决的是渲染阻塞的问题
  • requestIdleCallback 适合轻量级、非紧集任务,解决主线程阻塞问题。
  • web worker 适合处理复杂的计算任务,如大量数据处理、图像处理等,并在独立的线程中运行,避免阻塞主线程。
// 使用 requestIdleCallback 实现大量轻量级任务的调度 function performTasks(tasks) { if (tasks.length === 0) { return; } let i = 0; function _run() { requestIdleCallback((idle) => { while (i < tasks.length && idle.timeRemaining() > 0) { tasks[i++](); } if (i < tasks.length) { _run(); } }) } _run(); }
// 创建 Web Worker const worker = new Worker('worker.js'); // 监听 Worker 的返回消息 worker.onmessage = function(event) { console.log('主线程接收到数据: ' + event.data); }; // 向 Worker 发送消息 worker.postMessage('开始计算'); // 终止 Worker // worker.terminate();
onmessage = function(event) { console.log('Worker 接收到消息: ' + event.data); // 执行一个复杂计算任务 let result = 0; for (let i = 0; i < 1000000000000; i++) { result += i; } // 发送计算结果回主线程 postMessage(result); };
Previous
webpack - source-map 选择