Problem/Motivation
Whenever the Drupal.AjaxCommands.insert() command is fired, it attaches behaviors on the new content. But almost immediately afterwards, behaviors are attached again, but this time to the entire form. This results in the same DOM elements getting behaviors attached a second time.
Steps to reproduce
On a page that utilizes ajax
Use the browser inspector to see that Drupal.attachBehaviors(element, settings);
in ajax.js is called every time ajax is used.
Proposed resolution
Only attach when needed.
Remaining tasks
Review
User interface changes
NA
API changes
NA
Data model changes
NA
Release notes snippet
NA
Original Post
The Drupal AJAX system automatically attaches behaviors to newly inserted content. The most common way of inserting content is via #ajax['callback'], which inserts new form elements into a form.
Whenever the Drupal.AjaxCommands.insert() command is fired, it attaches behaviors on the new content. But almost immediately afterwards, behaviors are attached again, but this time to the entire form. This results in the same DOM elements getting behaviors attached a second time.
The documentation states helpfully:
// Reattach behaviors, if they were detached in beforeSerialize(). The
// attachBehaviors() called on the new content from processing the response
// commands is not sufficient, because behaviors from the entire form need
// to be reattached.
if (this.$form) {
const settings = this.settings || drupalSettings;
Drupal.attachBehaviors(this.$form.get(0), settings);
}
Which means, if we're attaching behaviors on the entire form, there's no need to attach behaviors on the individual elements. Adding a check to prevent this is easy and can save substantial processing client-side.