performance when appending to and emptying large lists

Viewed 236

I have several problems but I believe that they are all related. Essentially, Chrome 83 has become extremely slow to append to large select lists when the list size is greater than 1.

The following demonstrates my problem. All timings are rough averages of many tests. All testing was done with only a single tab open and minimal background activity on the testing computer.

Chrome 83

  • Append Single: 90ms
  • Append Multi: 12,000ms
  • Empty: 100ms

Chrome 81

  • Append Single: 90ms
  • Append Multi: 6,000ms
  • Empty: 7,000ms

Firefox 68

  • Append Single: 34ms
  • Append Multi: 35ms
  • Empty: 7,000ms

Safari 13

  • Append Single: 30ms
  • Append Multi: 40ms
  • Empty: 5ms

From this, it appears that there is a significant regression in performance for "append multi" from Chrome 81 -> Chrome 83, while "empty" improved significantly. Firefox is much more performant for appending than any Chrome version, but similarly poor at emptying.

I have tried this with document fragments as well, but performance is generally worse in all conditions.

Other than "don't use giant select lists", is there anything here that could be modified to improve performance of append, delete, or both?

var start;
function startTimer() {
  start = new Date();
}

function stopTimer() {
  document.getElementById("duration").innerHTML = (new Date() - start);
}

function append(id) {
  var select = document.getElementById(id);
  startTimer();
  var text = "";
  for (var i = 0; i < Number(document.getElementById("optionCount").value); i++) {
    text += "<option>" + "Value-is=" + i + "</option>";
  }
  select.innerHTML = text;
  stopTimer();
  return false;
}

function empty() {
  startTimer();
  document.getElementById("multiSelect").innerHTML = "";
  document.getElementById("singleSelect").innerHTML = "";
  stopTimer();
}
<div id="banner-message">
  # of options: <input type="text" id="optionCount" value="25000"/><br/><br/>
  
  Multi-select list: <select id="multiSelect" size="5"></select><br/>
  Single select list: <select id="singleSelect"></select><br/>
  <br/><br/>
  Duration: <span id="duration"></span> ms
</div>
<br/>

<button onclick="append('multiSelect')">Append Multi</button>
<button onclick="append('singleSelect')">Append Single</button>
<button onclick="empty()">Empty Both</button>

Edit: reported https://bugs.chromium.org/p/chromium/issues/detail?id=1094911

1 Answers

This is an interesting problem. I opened your snippet and inspected it with the Chrome DevTools' Performance tab and it showed an extremely large Cumulative Layout Shift. While that itself is not the issue it does mean that Chrome is, for some reason, qualifying this as some kind of layout change.

This is probably because the elements of the multi-select options do update a very large amount of content, but none of it is actually visible as it's outside of the selection box.

The issue is most likely a Chrome bug and something you can't get around. :(

Related