Что оказывает большее влияние на производительность: добавление дополнительного прослушивателя событий или необходимость многократного запроса DOM?

#javascript #performance #dom-events #coding-efficiency

Вопрос:

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

Мне сказали, что лучше объединить обработчики событий с делегированием событий, где это возможно. Мне также сказали, что если я могу избежать повторного запроса DOM для одного и того же элемента, лучше сделать это один раз и сохранить это на потом. Но в данном случае, похоже, мне нужно сделать то или другое, поэтому мне интересно, что дороже? В настоящее время у меня есть следующий код, который запускается один раз для настройки:

 buttons.forEach((button) => {
  const area = document.querySelector(`#${button.getAttribute('aria-controls')}`);   
        
  button.addEventListener('click', (e) => {
    // do some things with "area" and "button"
  });
});
 

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

 document.addEventListener('click', (e) => {
   if(e.target.classList.contains("button-class")) {
      const area = document.querySelector(`#${e.target.getAttribute('aria-controls')}`);
      // do some things with "area" and "button"
   }
});
 

Но стоит ли ради этого идти на компромисс, что теперь каждый раз, когда нажимается кнопка, я должен снова запрашивать соответствующий элемент «область»? Меняется ли ответ в зависимости от того, сколько у меня кнопок или как часто они будут нажиматься? Есть ли какой-то третий ответ, который более оптимален, чем любое из моих решений? Приношу извинения, если это действительно очевидный и глупый вопрос, но я искал в Google и просматривал другие вопросы о переполнении стека и действительно не могу найти ничего, чтобы ответить на этот вопрос.

Комментарии:

1. Что быстрее?

2. Если это «куча кнопок», вы не каждый раз запрашиваете один и тот же элемент, поэтому вы не можете этого избежать. Но запрос dom один раз при каждом щелчке все равно не повторяется. Совет избегать этого в основном относится к синхронным циклам (где это измеримо) или дублированному коду (что в любом случае является плохой практикой).

3. @Bergi Каждая кнопка сопряжена с одним другим элементом, поэтому, насколько я понимаю, при первом подходе эти элементы запрашиваются один раз при загрузке страницы и сохранении ссылок, а затем при нажатии на кнопки существующие ссылки могут быть использованы повторно. При втором подходе для каждого нажатия кнопки требуется новый запрос для связанного элемента.

4. @jamescodes Да, и ни один из подходов на самом деле не оказывает заметного влияния на производительность.

Ответ №1:

что дороже?

Как вы уже заметили, это компромисс. Затраты, которые вам нужно сравнить, соответственно

  • время выполнения, затраченное на инициализацию
  • время выполнения каждого обработчика щелчков
  • память, необходимая для сохранения состояния

Для всего лишь нескольких кнопок, которые нажимаются в обычных веб-потоках (а не, скажем, в инструменте тестирования APM), это действительно не имеет значения.

Комментарии:

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

2. @jamescodes Если мы не говорим о тысячах элементов или о нескольких вызовах querySelector за миллисекунду, вы не сможете заметить разницу.