Repository: angular/angular.js
File: src/ng/directive/ngOptions.js (JavaScript)

Code before:
        if (option.value !== element.value) element.value = option.selectValue;
      }

      function updateOptions() {
        var previousValue = options && selectCtrl.readValue();

        // We must remove all current options, but cannot simply set innerHTML = null
        // since the providedOption might have an ngIf on it that inserts comments which we must
        // preserve
        // Instead iterate over the current option elements and remove them or their optgroup
        // parents
        if (options) {
          for (var i = options.items.length - 1; i >= 0; i--) {
            var option = options.items[i];
            if (option.group) {
              jqLiteRemove(option.element.parentNode);
            } else {
              jqLiteRemove(option.element);
            }
          }
        }

        options = ngOptions.getOptions();

        var groupMap = {};
        var listFragment = $document[0].createDocumentFragment();

        // Ensure that the empty option is always there if it was explicitly provided
        if (providedEmptyOption) {
          selectElement.prepend(emptyOption);
        }

        options.items.forEach(function updateOption(option) {
          var group;
          var groupElement;
          var optionElement;

          if (isDefined(option.group)) {

            // This option is to live in a group
            // See if we have already created this group
            group = groupMap[option.group];

            if (!group) {

              groupElement = optGroupTemplate.cloneNode(false);
              listFragment.appendChild(groupElement);

              // Update the label on the group element
              groupElement.label = option.group;


Review comment (performance):
It doesn't lookt like the muliple jqLiteRemove affects performance too much, so I would like to keep it like that for simplicity


Code after:
        // NOTE: The label must be set before the value, otherwise IE10/11/EDGE create unresponsive
        // selects in certain circumstances when multiple selects are next to each other and display
        // the option list in listbox style, i.e. the select is [multiple], or specifies a [size].
        // See https://github.com/angular/angular.js/issues/11314 for more info.
        // This is unfortunately untestable with unit / e2e tests
        if (option.label !== element.label) {
          element.label = option.label;
          element.textContent = option.label;
        }
        if (option.value !== element.value) element.value = option.selectValue;
      }

      function updateOptions() {
        var previousValue = options && selectCtrl.readValue();

        // We must remove all current options, but cannot simply set innerHTML = null
        // since the providedEmptyOption might have an ngIf on it that inserts comments which we
        // must preserve.
        // Instead, iterate over the current option elements and remove them or their optgroup
        // parents
        if (options) {

          for (var i = options.items.length - 1; i >= 0; i--) {
            var option = options.items[i];
            if (option.group) {
              jqLiteRemove(option.element.parentNode);
            } else {
              jqLiteRemove(option.element);
            }
          }
        }

        options = ngOptions.getOptions();

        var groupElementMap = {};

        // Ensure that the empty option is always there if it was explicitly provided
        if (providedEmptyOption) {
          selectElement.prepend(emptyOption);
        }

        options.items.forEach(function addOption(option) {
          var groupElement;

          if (isDefined(option.group)) {

            // This option is to live in a group
            // See if we have already created this group
            groupElement = groupElementMap[option.group];

            if (!groupElement) {