Home / Function/ performWorkOnRootViaSchedulerTask() — react Function Reference

performWorkOnRootViaSchedulerTask() — react Function Reference

Architecture documentation for the performWorkOnRootViaSchedulerTask() function in ReactFiberRootScheduler.js from the react codebase.

Entity Profile

Dependency Diagram

graph TD
  1c7960af_fcd5_d6c9_ece2_ba8ee42ad12c["performWorkOnRootViaSchedulerTask()"]
  a22f22c8_f97a_86c8_be5a_4b91a6a21eab["ReactFiberRootScheduler.js"]
  1c7960af_fcd5_d6c9_ece2_ba8ee42ad12c -->|defined in| a22f22c8_f97a_86c8_be5a_4b91a6a21eab
  2f0b078e_5ecb_a4c3_220a_f89cb5bd5a89["scheduleTaskForRootDuringMicrotask()"]
  1c7960af_fcd5_d6c9_ece2_ba8ee42ad12c -->|calls| 2f0b078e_5ecb_a4c3_220a_f89cb5bd5a89
  style 1c7960af_fcd5_d6c9_ece2_ba8ee42ad12c fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

packages/react-reconciler/src/ReactFiberRootScheduler.js lines 513–606

function performWorkOnRootViaSchedulerTask(
  root: FiberRoot,
  didTimeout: boolean,
): RenderTaskFn | null {
  // This is the entry point for concurrent tasks scheduled via Scheduler (and
  // postTask, in the future).

  if (enableProfilerTimer && enableProfilerNestedUpdatePhase) {
    resetNestedUpdateFlag();
  }

  if (enableProfilerTimer && enableComponentPerformanceTrack) {
    // Track the currently executing event if there is one so we can ignore this
    // event when logging events.
    trackSchedulerEvent();
  }

  if (hasPendingCommitEffects()) {
    // We are currently in the middle of an async committing (such as a View Transition).
    // We could force these to flush eagerly but it's better to defer any work until
    // it finishes. This may not be the same root as we're waiting on.
    // TODO: This relies on the commit eventually calling ensureRootIsScheduled which
    // always calls processRootScheduleInMicrotask which in turn always loops through
    // all the roots to figure out. This is all a bit inefficient and if optimized
    // it'll need to consider rescheduling a task for any skipped roots.
    root.callbackNode = null;
    root.callbackPriority = NoLane;
    return null;
  }

  // Flush any pending passive effects before deciding which lanes to work on,
  // in case they schedule additional work.
  const originalCallbackNode = root.callbackNode;
  const didFlushPassiveEffects = flushPendingEffectsDelayed();
  if (didFlushPassiveEffects) {
    // Something in the passive effect phase may have canceled the current task.
    // Check if the task node for this root was changed.
    if (root.callbackNode !== originalCallbackNode) {
      // The current task was canceled. Exit. We don't need to call
      // `ensureRootIsScheduled` because the check above implies either that
      // there's a new task, or that there's no remaining work on this root.
      return null;
    } else {
      // Current task was not canceled. Continue.
    }
  }

  // Determine the next lanes to work on, using the fields stored on the root.
  // TODO: We already called getNextLanes when we scheduled the callback; we
  // should be able to avoid calling it again by stashing the result on the
  // root object. However, because we always schedule the callback during
  // a microtask (scheduleTaskForRootDuringMicrotask), it's possible that
  // an update was scheduled earlier during this same browser task (and
  // therefore before the microtasks have run). That's because Scheduler batches
  // together multiple callbacks into a single browser macrotask, without
  // yielding to microtasks in between. We should probably change this to align
  // with the postTask behavior (and literally use postTask when
  // it's available).
  const workInProgressRoot = getWorkInProgressRoot();
  const workInProgressRootRenderLanes = getWorkInProgressRootRenderLanes();
  const rootHasPendingCommit =
    root.cancelPendingCommit !== null || root.timeoutHandle !== noTimeout;
  const lanes = getNextLanes(
    root,
    root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,
    rootHasPendingCommit,
  );
  if (lanes === NoLanes) {
    // No more work on this root.
    return null;
  }

  // Enter the work loop.
  // TODO: We only check `didTimeout` defensively, to account for a Scheduler
  // bug we're still investigating. Once the bug in Scheduler is fixed,
  // we can remove this, since we track expiration ourselves.
  const forceSync = !disableSchedulerTimeoutInWorkLoop && didTimeout;
  performWorkOnRoot(root, lanes, forceSync);

  // The work loop yielded, but there may or may not be work left at the current
  // priority. Need to determine whether we need to schedule a continuation.

Domain

Subdomains

Frequently Asked Questions

What does performWorkOnRootViaSchedulerTask() do?
performWorkOnRootViaSchedulerTask() is a function in the react codebase, defined in packages/react-reconciler/src/ReactFiberRootScheduler.js.
Where is performWorkOnRootViaSchedulerTask() defined?
performWorkOnRootViaSchedulerTask() is defined in packages/react-reconciler/src/ReactFiberRootScheduler.js at line 513.
What does performWorkOnRootViaSchedulerTask() call?
performWorkOnRootViaSchedulerTask() calls 1 function(s): scheduleTaskForRootDuringMicrotask.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free