Перейти к основному содержимому

Способы разделения задач в JavaScript

··273 слов·2 минут·
Александр Мунько
Автор
Александр Мунько
Любитель порассказывать про Фронтенд
Оригинальная статья

Таски. Они везде, мы постоянно пишем код, который можно назвать тасками. Разделить их тоже можем — на макротаски и микротаски, хоть это и не всегда верное утверждение1. Для простоты назовем весь синхронный код, где бы он не вызвался - макротасками. Использование макротасок заставляет и браузер выполнять определенные процессы внутри них, например reflow2 и repaint3. Такое поведение может стать бутылочным горлышком в некоторых сценариях, например расчет размеров элементов, особенно если их много. Решением может быть разделение макротаски на несколько макротасок.

Как много вы можете придумать способов разбиения долгих макротасок? Я смог придумать только 3 — setTimeout, requestAnimationFrame, requestIdleCallback, и оказалось, что не все способы хороши. А вот Алекс МакАртур, автор статьи «Способы разбиения длинных задач в JavaScript» рассказал больше способов:

  • setTimeout;
  • async/await & setTimeout;
  • scheduler.postTask();
  • scheduler.yield();
  • requestAnimationFrame();
  • MessageChannel();
  • и использование Web Workers.

А вот использование requestIdleCallback автор исключает, т.к. он не гарантирует исполнение кода.

Не стоит забывать про requestIdleCallback

Данная функция является очень важной для оптимизации приложений, например тех же часто вызывающихся reflow. Функция попросит браузер найти “окошко” для его исполнения, хоть оно может и найтись сильно позже.

Как отмечает автор, лучшим вариантом является scheduler.yield(), но пока Scheduler есть только в Хроме мы можем использовать подход с async/await & setTimeout:

await new Promise((resolve) => setTimeout(resolve, 0));

  1. В спецификации ECMAScript нет прямого упоминания “макрозадач” и “микрозадач”, данные термины удобны в рамках описания работы Event Loop. ↩︎

  2. Процесс, при котором браузер пересчитывает позиции и размеры элементов. Может вызвано обращением к clientHeight, clientWidth и т.д., подробнее описано в What forces layout / reflow↩︎

  3. Процесс, при котором браузер перерисовывает изменения, затронутые reflow. ↩︎