React 源码7:Lane、React和schedule优先级转换

发布于:2025-07-17 ⋅ 阅读:(18) ⋅ 点赞:(0)

在《源码3》requestUpdateLane函数根据eventLane获取不同情况对应优先级。

一、优先级

1.Lane的tag

一共有32种lane。

var TotalLanes = 31;
var NoLanes =
/*                        */
0;
var NoLane =
/*                          */
0;
var SyncLane =
/*                        */
1;
var InputContinuousHydrationLane =
/*    */
2;
var InputContinuousLane =
/*             */
4;
var DefaultHydrationLane =
/*            */
8;
var DefaultLane =
/*                     */
16;
var TransitionHydrationLane =
/*                */
32;
var TransitionLanes =
/*                       */
4194240;
var TransitionLane1 =
/*                        */
64;
var TransitionLane2 =
/*                        */
128;
var TransitionLane3 =
/*                        */
256;
var TransitionLane4 =
/*                        */
512;
var TransitionLane5 =
/*                        */
1024;
var TransitionLane6 =
/*                        */
2048;
var TransitionLane7 =
/*                        */
4096;
var TransitionLane8 =
/*                        */
8192;
var TransitionLane9 =
/*                        */
16384;
var TransitionLane10 =
/*                       */
32768;
var TransitionLane11 =
/*                       */
65536;
var TransitionLane12 =
/*                       */
131072;
var TransitionLane13 =
/*                       */
262144;
var TransitionLane14 =
/*                       */
524288;
var TransitionLane15 =
/*                       */
1048576;
var TransitionLane16 =
/*                       */
2097152;
var RetryLanes =
/*                            */
130023424;
var RetryLane1 =
/*                             */
4194304;
var RetryLane2 =
/*                             */
8388608;
var RetryLane3 =
/*                             */
16777216;
var RetryLane4 =
/*                             */
33554432;
var RetryLane5 =
/*                             */
67108864;
var SomeRetryLane = RetryLane1;
var SelectiveHydrationLane =
/*          */
134217728;
var NonIdleLanes =
/*                          */
268435455;
var IdleHydrationLane =
/*               */
268435456;
var IdleLane =
/*                        */
536870912;
var OffscreenLane =
/*                   */
1073741824; // This function is used for the experimental timeline (react-devtools-timeline)
// It should be kept in sync with the Lanes values above.

2.React中事件对应的优先级(获取事件对应的优先级getEventPriority函数)

一共有4种优先级。

在getEventPriority中获取事件对应的react优先级,有:

  • DiscreteEventPriority(离散事件优先级)
  • ContinuousEventPriority(连续事件优先级)

  • DefaultEventPriority(默认优先级)

  • IdleEventPriority(空间时间优先级)

function getEventPriority(domEventName) {
  switch (domEventName) {
    // Used by SimpleEventPlugin:
    case 'cancel':
    case 'click':
    case 'close':
    case 'contextmenu':
    case 'copy':
    case 'cut':
    case 'auxclick':
    case 'dblclick':
    case 'dragend':
    case 'dragstart':
    case 'drop':
    case 'focusin':
    case 'focusout':
    case 'input':
    case 'invalid':
    case 'keydown':
    case 'keypress':
    case 'keyup':
    case 'mousedown':
    case 'mouseup':
    case 'paste':
    case 'pause':
    case 'play':
    case 'pointercancel':
    case 'pointerdown':
    case 'pointerup':
    case 'ratechange':
    case 'reset':
    case 'resize':
    case 'seeked':
    case 'submit':
    case 'touchcancel':
    case 'touchend':
    case 'touchstart':
    case 'volumechange': // Used by polyfills:
    // eslint-disable-next-line no-fallthrough

    case 'change':
    case 'selectionchange':
    case 'textInput':
    case 'compositionstart':
    case 'compositionend':
    case 'compositionupdate': // Only enableCreateEventHandleAPI:
    // eslint-disable-next-line no-fallthrough

    case 'beforeblur':
    case 'afterblur': // Not used by React but could be by user code:
    // eslint-disable-next-line no-fallthrough

    case 'beforeinput':
    case 'blur':
    case 'fullscreenchange':
    case 'focus':
    case 'hashchange':
    case 'popstate':
    case 'select':
    case 'selectstart':
      return DiscreteEventPriority;

    case 'drag':
    case 'dragenter':
    case 'dragexit':
    case 'dragleave':
    case 'dragover':
    case 'mousemove':
    case 'mouseout':
    case 'mouseover':
    case 'pointermove':
    case 'pointerout':
    case 'pointerover':
    case 'scroll':
    case 'toggle':
    case 'touchmove':
    case 'wheel': // Not used by React but could be by user code:
    // eslint-disable-next-line no-fallthrough

    case 'mouseenter':
    case 'mouseleave':
    case 'pointerenter':
    case 'pointerleave':
      return ContinuousEventPriority;

    case 'message':
      {
        // We might be in the Scheduler callback.
        // Eventually this mechanism will be replaced by a check
        // of the current priority on the native scheduler.

        //见shceduler优先级转换为React优先级
      }

    default:
      return DefaultEventPriority;
  }
}

3.schedule中的优先级

一共有5种优先级。

var ImmediatePriority = Scheduler.unstable_ImmediatePriority;
var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority;
var NormalPriority = Scheduler.unstable_NormalPriority;
var LowPriority = Scheduler.unstable_LowPriority;
var IdlePriority = Scheduler.unstable_IdlePriority;

const unstable_ImmediatePriority = 1;
const unstable_UserBlockingPriority = 2;
const unstable_NormalPriority = 3;
const unstable_IdlePriority = 5;
const unstable_LowPriority = 4;

二、优先级转换的函数

1. lanes优先级转换为React优先级

lane和React全局对应关系:

var DiscreteEventPriority = SyncLane;
var ContinuousEventPriority = InputContinuousLane;
var DefaultEventPriority = DefaultLane;
var IdleEventPriority = IdleLane;
var currentUpdatePriority = NoLane;

lane与React优先级转换: 

function lanesToEventPriority(lanes) {
  var lane = getHighestPriorityLane(lanes);

  if (!isHigherEventPriority(DiscreteEventPriority, lane)) {
    return DiscreteEventPriority;
  }

  if (!isHigherEventPriority(ContinuousEventPriority, lane)) {
    return ContinuousEventPriority;
  }

  if (includesNonIdleWork(lane)) {
    return DefaultEventPriority;
  }

  return IdleEventPriority;
}

2. React优先级转换为scheduler优先级

var schedulerPriorityLevel;

switch (lanesToEventPriority(nextLanes)) {
	case DiscreteEventPriority:
		schedulerPriorityLevel = ImmediatePriority;
		break;

	case ContinuousEventPriority:
		schedulerPriorityLevel = UserBlockingPriority;
		break;

	case DefaultEventPriority:
		schedulerPriorityLevel = NormalPriority;
		break;

	case IdleEventPriority:
		schedulerPriorityLevel = IdlePriority;
		break;

	default:
		schedulerPriorityLevel = NormalPriority;
		break;
}

3.scheduler优先级转换为React优先级

// We might be in the Scheduler callback.
// Eventually this mechanism will be replaced by a check
// of the current priority on the native scheduler.
var schedulerPriority = getCurrentPriorityLevel();

switch (schedulerPriority) {
	case ImmediatePriority:
		return DiscreteEventPriority;

	case UserBlockingPriority:
		return ContinuousEventPriority;

	case NormalPriority:
	case LowPriority:
		// TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration.
		return DefaultEventPriority;

	case IdlePriority:
		return IdleEventPriority;

	default:
		return DefaultEventPriority;
}

三、requestUpdateLane函数

暂不考虑transition情况,优先级有四种返回情况:

  1. 非并发模式,产生同步优先级

  2. render阶段产生的 update,返回 render 阶段进行中的优先级

  3. 使用手动设置的优先级

  4. 如果没有手动设置的优先级,则获取当前事件的优先级。

function requestUpdateLane(fiber) {
	var mode = fiber.mode;

	if ((mode & ConcurrentMode) === NoMode) {
		//非并发模式,产生同步优先级
		return SyncLane;
	} else if (
		(executionContext & RenderContext) !== NoContext &&
		workInProgressRootRenderLanes !== NoLanes
	) {
		// render阶段产生的 update,返回 render 阶段进行中的优先级
		return pickArbitraryLane(workInProgressRootRenderLanes);
	}

	//transition情况暂不做讨论

	//使用手动设置的优先级
	var updateLane = getCurrentUpdatePriority();

	if (updateLane !== NoLane) {
		return updateLane;
	}

	//如果没有手动设置的优先级,则获取当前事件的优先级
	var eventLane = getCurrentEventPriority();
	return eventLane;
}

function getCurrentEventPriority() {
	var currentEvent = window.event;

	if (currentEvent === undefined) {
		return DefaultEventPriority;
	}

	//详见本文(一、优先级)第二节getEventPriority函数,返回React优先级
	return getEventPriority(currentEvent.type);
}

//currentUpdatePriority是存储优先级的全局变量
function getCurrentUpdatePriority() {
	return currentUpdatePriority;
}

 


网站公告

今日签到

点亮在社区的每一天
去签到