Repository: facebook/react
File: packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js (JavaScript)

Code before:
    (newProps.src !== oldProps.src || newProps.srcSet !== oldProps.srcSet)
  );
}

export function maySuspendCommitInSyncRender(
  type: Type,
  props: Props,
): boolean {
  // TODO: Allow sync lanes to suspend too with an opt-in.
  return false;
}

export function mayResourceSuspendCommit(resource: Resource): boolean {
  return (
    resource.type === 'stylesheet' &&
    (resource.state.loading & Inserted) === NotLoaded
  );
}

export function preloadInstance(type: Type, props: Props): boolean {
  // We don't need to preload Suspensey images because the browser will
  // load them early once we set the src.
  // We indicate that all images are not yet loaded and if they're able
  // to hit cache we let the decode() do that. Even if we did maintain
  // our own cache to know this, it's not a guarantee that the browser
  // keeps it in decoded memory.
  return false;
}

export function preloadResource(resource: Resource): boolean {
  if (
    resource.type === 'stylesheet' &&
    (resource.state.loading & Settled) === NotLoaded
  ) {
    // Return false to indicate this resource should suspend
    return false;
  }

  // Return true to indicate this resource should not suspend
  return true;
}

type SuspendedState = {
  stylesheets: null | Map<StylesheetResource, HoistableRoot>,
  count: number,
  unsuspend: null | (() => void),
};
let suspendedState: null | SuspendedState = null;

// We use a noop function when we begin suspending because if possible we want the
// waitfor step to finish synchronously. If it doesn't we'll return a function to

Review comment (performance):
The consequence of this is that we end up showing fallbacks for a Suspense boundary in a Transition even if we've preloaded it before revealing it (which its is throttled in its reveal).

We might want to add a heuristic here in case it is synchronously available to let it commit anyway. Even though that can lead to flashes due to images not being decoded.

The Suspense optimization could help here because we could yield and see if we can eagerly solve it in a micro-task however that could force decoding a bit too early which gives opportunity for the decoding cache to get dropped before commit.

I think instead, what might be ideal is to detect if an image is already loaded and if so, only mark the commit as might suspend but not suspend the Suspense boundary. I think I'll do that.

Code after:
    (newProps.src !== oldProps.src || newProps.srcSet !== oldProps.srcSet)
  );
}

export function maySuspendCommitInSyncRender(
  type: Type,
  props: Props,
): boolean {
  // TODO: Allow sync lanes to suspend too with an opt-in.
  return false;
}

export function mayResourceSuspendCommit(resource: Resource): boolean {
  return (
    resource.type === 'stylesheet' &&
    (resource.state.loading & Inserted) === NotLoaded
  );
}

export function preloadInstance(
  instance: Instance,
  type: Type,
  props: Props,
): boolean {
  // We don't need to preload Suspensey images because the browser will
  // load them early once we set the src.
  // If we return true here, we'll still get a suspendInstance call in the
  // pre-commit phase to determine if we still need to decode the image or
  // if was dropped from cache. This just avoids rendering Suspense fallback.
  return !!(instance: any).complete;
}

export function preloadResource(resource: Resource): boolean {
  if (
    resource.type === 'stylesheet' &&
    (resource.state.loading & Settled) === NotLoaded
  ) {
    // Return false to indicate this resource should suspend
    return false;
  }

  // Return true to indicate this resource should not suspend
  return true;
}

type SuspendedState = {
  stylesheets: null | Map<StylesheetResource, HoistableRoot>,
  count: number,
  unsuspend: null | (() => void),
};
let suspendedState: null | SuspendedState = null;