React: При каких обстоятельствах unstable_shouldYield вернет true?

Созданный на 8 февр. 2019  ·  4Комментарии  ·  Источник: facebook/react

В Scheduler.js

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

unstable_shouldYield () возвращает true, если currentDidTimeout имеет значение false, а shouldYieldToHost () возвращает true, но почему?

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

shouldYieldToHost () return true означает, что в этом периоде простоя не осталось времени
currentDidTimeout false означает, что расписание не тайм-аут
какие отношения между ними, почему unstable_shouldYield () зависит от них?

Question

Самый полезный комментарий

Мы периодически подчиняемся среде хоста - каждые 16 мс или около того - чтобы позволить браузеру обрабатывать входящие события, включая ввод данных пользователем. frameDeadline - это отметка времени, которую мы планируем выдать (изначально задано что-то вроде now() + 16ms ), поэтому shouldYieldToHost возвращает true по истечении этого времени. Затем мы используем некоторую комбинацию requestIdleCallback и requestAnimationFrame, чтобы мы могли вскоре обработать следующую часть работы.

В идеальном случае мы можем закончить весь рендеринг этими небольшими фрагментами по 16 мс. Однако, если одновременно происходит много других вещей, работа с React может «голодать» и не сможет полностью отрисоваться в маленьких фрагментах. Итак, у нас есть вторая проверка: каждый ожидающий рендеринг или обновление состояния имеет «время истечения» (обычно где-то от 100 мс до 5000 мс) - если это время проходит без завершения рендеринга, мы переключаемся в синхронный режим до тех пор, пока это обновление не будет завершено. Это не идеально, но гарантирует, что все обновления будут обрабатываться без слишком долгого ожидания.

Мы устанавливаем таймер в браузере (например, с помощью setTimeout) на то же время истечения срока. Если этот таймер сработает, мы знаем, что нам нужно выполнить работу синхронно. Если это произойдет, currentDidTimeout будет иметь значение true, поэтому мы не уступим.

В будущем мы планируем использовать новый isInputPending API-интерфейс браузера (https://github.com/WICG/is-input-pending), чтобы мы могли продолжить работу и уступить только при вводе нового пользователя. вместо того, чтобы всегда выдавать каждые 16 мсек.

Все 4 Комментарий

Мы периодически подчиняемся среде хоста - каждые 16 мс или около того - чтобы позволить браузеру обрабатывать входящие события, включая ввод данных пользователем. frameDeadline - это отметка времени, которую мы планируем выдать (изначально задано что-то вроде now() + 16ms ), поэтому shouldYieldToHost возвращает true по истечении этого времени. Затем мы используем некоторую комбинацию requestIdleCallback и requestAnimationFrame, чтобы мы могли вскоре обработать следующую часть работы.

В идеальном случае мы можем закончить весь рендеринг этими небольшими фрагментами по 16 мс. Однако, если одновременно происходит много других вещей, работа с React может «голодать» и не сможет полностью отрисоваться в маленьких фрагментах. Итак, у нас есть вторая проверка: каждый ожидающий рендеринг или обновление состояния имеет «время истечения» (обычно где-то от 100 мс до 5000 мс) - если это время проходит без завершения рендеринга, мы переключаемся в синхронный режим до тех пор, пока это обновление не будет завершено. Это не идеально, но гарантирует, что все обновления будут обрабатываться без слишком долгого ожидания.

Мы устанавливаем таймер в браузере (например, с помощью setTimeout) на то же время истечения срока. Если этот таймер сработает, мы знаем, что нам нужно выполнить работу синхронно. Если это произойдет, currentDidTimeout будет иметь значение true, поэтому мы не уступим.

В будущем мы планируем использовать новый isInputPending API-интерфейс браузера (https://github.com/WICG/is-input-pending), чтобы мы могли продолжить работу и уступить только при вводе нового пользователя. вместо того, чтобы всегда выдавать каждые 16 мсек.

Спасибо за ответ
У меня еще есть вопросы,

  1. Я думаю, что unstable_shouldYield() обозначают, можно ли прервать работу или нет в расписании, это правильно?
  2. Относятся ли «16 мс» к activeFrameTime ?
  3. Когда firstCallbackNode.expirationTime < currentExpirationTime вернет true? Означает ли это, что приоритет следующей работы выше, чем у предыдущей?
  1. Каждая задача рендеринга должна часто проверять unstable_shouldYield (). (Мы вызываем его примерно после каждого компонента в дереве.) В большинстве случаев он возвращает false (что означает продолжение работы), но когда он возвращает true, это означает, что рендеринг необходимо приостановить.

  2. Да.

  3. Я считаю, что это условие истинно, если какая-то новая работа с более высоким приоритетом ставится в очередь во время существующей визуализации. В этом случае мы хотим вернуть true, чтобы мы могли переключиться на эту задачу.

Спасибо большое, это очень мило с вашей стороны!

Была ли эта страница полезной?
0 / 5 - 0 рейтинги