React: Dans quelles circonstances, unstable_shouldYield retournera true?

Créé le 8 févr. 2019  ·  4Commentaires  ·  Source: facebook/react

Dans Scheduler.js,

function unstable_shouldYield() {
  return (
    !currentDidTimeout &&
    ((firstCallbackNode !== null &&
      firstCallbackNode.expirationTime < currentExpirationTime) ||
      shouldYieldToHost())
  );
}

unstable_shouldYield () renvoie true lorsque currentDidTimeout est false et shouldYieldToHost () renvoie true, mais pourquoi?

shouldYieldToHost = function() {
  return frameDeadline <= getCurrentTime();
};

shouldYieldToHost () return true signifie qu'il ne reste plus de temps dans cette période d'inactivité
currentDidTimeout est false signifie que la planification n'est pas expirée
quelle relation entre eux, pourquoi unstable_shouldYield () en dépend-il?

Question

Commentaire le plus utile

Nous cédons périodiquement à l'environnement hôte - toutes les 16 ms environ - pour permettre à la navigation de traiter les événements entrants, y compris les entrées utilisateur. frameDeadline est l'horodatage auquel nous prévoyons de produire (défini à l'origine sur quelque chose comme now() + 16ms ), donc shouldYieldToHost renvoie true une fois que ce temps est passé. Ensuite, nous utilisons une combinaison de requestIdleCallback et requestAnimationFrame afin que nous puissions traiter le prochain travail bientôt.

Dans l'idéal, on peut terminer tout le rendu dans ces petites tranches de 16ms. Cependant, s'il y a beaucoup d'autres choses qui se produisent en même temps, le travail de React peut "mourir de faim" et ne pas être en mesure de rendre complètement dans les petites tranches. Nous avons donc une deuxième vérification: chaque rendu ou mise à jour d'état en attente a un "temps d'expiration" (généralement entre 100 ms et 5000 ms) - si ce temps passe sans que le rendu ne se termine, nous passons en mode synchrone jusqu'à ce que cette mise à jour puisse être terminée. Ce n'est pas idéal, mais cela garantit que toutes les mises à jour sont traitées sans attendre trop longtemps.

Nous définissons une minuterie dans le navigateur (par exemple, avec setTimeout) pour ce même délai d'expiration. Si cette minuterie se déclenche, nous savons que nous devons effectuer le travail de manière synchrone. Si cela se produit, currentDidTimeout est défini sur true, nous ne céderons donc pas.

À l'avenir, nous prévoyons d'utiliser une nouvelle API de navigateur isInputPending (https://github.com/WICG/is-input-pending) afin de pouvoir continuer le travail de traitement et de ne produire que lorsqu'il y a une nouvelle entrée d'utilisateur. , au lieu de toujours donner toutes les 16 ms.

Tous les 4 commentaires

Nous cédons périodiquement à l'environnement hôte - toutes les 16 ms environ - pour permettre à la navigation de traiter les événements entrants, y compris les entrées utilisateur. frameDeadline est l'horodatage auquel nous prévoyons de produire (défini à l'origine sur quelque chose comme now() + 16ms ), donc shouldYieldToHost renvoie true une fois que ce temps est passé. Ensuite, nous utilisons une combinaison de requestIdleCallback et requestAnimationFrame afin que nous puissions traiter le prochain travail bientôt.

Dans l'idéal, on peut terminer tout le rendu dans ces petites tranches de 16ms. Cependant, s'il y a beaucoup d'autres choses qui se produisent en même temps, le travail de React peut "mourir de faim" et ne pas être en mesure de rendre complètement dans les petites tranches. Nous avons donc une deuxième vérification: chaque rendu ou mise à jour d'état en attente a un "temps d'expiration" (généralement entre 100 ms et 5000 ms) - si ce temps passe sans que le rendu ne se termine, nous passons en mode synchrone jusqu'à ce que cette mise à jour puisse être terminée. Ce n'est pas idéal, mais cela garantit que toutes les mises à jour sont traitées sans attendre trop longtemps.

Nous définissons une minuterie dans le navigateur (par exemple, avec setTimeout) pour ce même délai d'expiration. Si cette minuterie se déclenche, nous savons que nous devons effectuer le travail de manière synchrone. Si cela se produit, currentDidTimeout est défini sur true, nous ne céderons donc pas.

À l'avenir, nous prévoyons d'utiliser une nouvelle API de navigateur isInputPending (https://github.com/WICG/is-input-pending) afin de pouvoir continuer le travail de traitement et de ne produire que lorsqu'il y a une nouvelle entrée d'utilisateur. , au lieu de toujours donner toutes les 16 ms.

Merci pour votre réponse
J'ai encore des questions,

  1. Je pense que unstable_shouldYield() représente si le travail peut être interrompu ou non dans le calendrier, est-ce exact?
  2. Est-ce que "16ms" fait référence à activeFrameTime ?
  3. Quand firstCallbackNode.expirationTime < currentExpirationTime retournera-t-il vrai? Cela signifie-t-il que la priorité du prochain travail est plus élevée que la précédente?
  1. Chaque tâche de rendu doit vérifier fréquemment unstable_shouldYield (). (Nous l'appelons à peu près après chaque composant de l'arborescence.) La plupart du temps, il retournera false (ce qui signifie continuer) mais quand il retourne true, cela signifie que le rendu doit être mis en pause.

  2. Oui.

  3. Je crois que cette condition est vraie si un travail plus récent et plus prioritaire est mis en file d'attente pendant un rendu existant. Dans ce cas, nous voulons retourner true afin de pouvoir passer à cette tâche.

Merci beaucoup, c'est vraiment gentil de votre part!

Cette page vous a été utile?
0 / 5 - 0 notes