Чтение и запись свойств макета - это страшные вещи в интерфейсном JavaScript, если вы вообще заботитесь о производительности. Плохие слова, такие как "сбой" или "принудительная синхронизация", начинают преследовать вас по ночам.

Давайте немного проясним ситуацию, ладно?

Нет никакого внутреннего вреда, связанного с чтением и написанием макета в JavaScript. Насколько я понимаю, основная проблема связана с когда вы это делаете.

Нет никакого внутреннего вреда, связанного с чтением и написанием макета в JavaScript.

Взгляните на этот код, он повлияет на производительность?

// some code
readLayout();
writeLayout();
// some other code

Может быть. В течение кадра JavaScript выполняется в последнюю очередь после того, как браузер вычисляет, где объекты должны быть нарисованы.

Simplified frame:  
| Layout | Paint | JavaScript |

Проблема, возникающая с этим фрагментом кода, заключается в том, что, поскольку мы пишем макет, браузер вынужден пересчитывать макет и перерисовывать, расширяя текущий кадр за пределы допустимой продолжительности.

| Layout | Paint | JavaScript | Layout | Paint |

Стандартным решением было бы запросить браузер выполнить код JavaScript для написания макета в начале следующего кадра, прежде чем он вычислит макет. Как? Через requestAnimationFrame.

requestAnimationFrame( function() {
   readLayout();
   writeLayout();
} );

Здесь выполняется обратный вызов rAF:

| rAF | Layout | Paint | JavaScript |

Намного лучше. Однако обратите особое внимание на вызов readLayout (). Поскольку мы находимся в начале кадра, мы можем использовать эту уникальную позицию для доступа к информации относительно предыдущего кадра. Однако если бы мы сделали эту информацию недействительной, написав макет перед чтением, мы заставили бы браузер запускать процессы макета и стилей раньше времени.

В любом случае, как правило, можно просто иметь в виду следующее:

  1. Группируйте свои записи в обратном вызове requestAnimationFrame
  2. Группируйте чтение перед записью

Если вы нашли этот пост вообще полезным, нажмите кнопку ❤! Я читаю каждый комментарий, так что не забудьте поделиться своими мыслями в разговоре!