6

现在我正在使用以下代码,但在 Chrome 上大约需要 10 秒,在 IE11 上大约需要 2 分钟,这是它最终会被使用的地方。

for (var key in dict) {
    if (dict.hasOwnProperty(key)) {
        combo.innerHTML += "<option value=\"" + dict[key] + "\">" + key + "</option>";
    }
}

我正在阅读本教程:http ://blog.teamtreehouse.com/creating-autocomplete-dropdowns-datalist-element建议在处理较大数量时像这样使用ajax,但我不确定大是指100个项目还是100,000 件商品。

var request = new XMLHttpRequest();

request.onreadystatechange = function(response) {
  if (request.readyState === 4) {
    if (request.status === 200) {

      var jsonOptions = JSON.parse(request.responseText);

      jsonOptions.forEach(function(item) {

        var option = document.createElement('option');
        option.value = item;
        dataList.appendChild(option);

      });

    } else {
      console.log("Failed to load datalist options");
    }
  }
};

request.open('GET', 'html-elements.json', true);
request.send();

我一直试图通过替换来让它在字典中工作request.responseTextJSON.parse(JSON.stringify(dict));但我遇到了问题,因为它不在文件中,所以让它开始发出请求。

我该怎么做?如果我不应该为此使用 DataList,你推荐什么替代方案?

提前致谢。

4

4 回答 4

7

您可以提高性能的一个领域是使用文档片段,因为写入 DOM 很慢。

var frag = document.createDocumentFragment();

for (var key in dict) {
    if (dict.hasOwnProperty(key)) {
        var option = document.createElement("OPTION");
        option.textContent = key;
        option.value = dict[key];
        frag.appendChild(option);
    }
}

combo.appendChild(frag);
于 2015-05-19T21:39:55.983 回答
2

获得更好性能的即时方法是首先构建 HTML 字符串,然后将其分配给 innerHTML。

var htmlStr = '';
for (var key in dict) {
    if (dict.hasOwnProperty(key)) {
        htmlStr += "<option value=\"" + dict[key] + "\">" + key + "</option>";
    }
}
combo.innerHTML = htmlStr;

差异很大:http: //jsperf.com/string-append-vs-dom

于 2015-05-19T21:49:33.730 回答
1

DOM 是出了名的慢。您可以尝试手动过滤并仅显示第一个 X 元素。正如 znap026 所指出的,使用文档片段也有助于加快速度。

"use strict";

var data = Object.getOwnPropertyNames(window).sort(),
  datalist = document.getElementById("datalist"),
  input = document.getElementById("input");
  
const processedData = Object.fromEntries(data.map(d => [d.toLowerCase(), d]));

function search() {
  var term = input.value.toLowerCase();
  var found = 0;
  var frag = document.createDocumentFragment();

  for (var child of [].slice.apply(datalist.childNodes)) {
    datalist.removeChild(child);
  }

  for (var searchable in processedData) {
    if (searchable.indexOf(term) === 0) {
      let item = processedData[searchable];
      let option = document.createElement("option");
      option.value = item

      frag.appendChild(option);
      if (++found > 10) break;
    }
  }

  datalist.appendChild(frag);
}

search();
input.addEventListener("input", search);
<input id="input" list="datalist" placeholder="window properties"/>
<datalist id="datalist"></datalist>

于 2015-05-19T22:27:52.463 回答
1

您还可以通过从输入中分离数据列表,然后在填充后再次附加它来提高性能:

"use strict";

// init
const values = Object.getOwnPropertyNames(window);
const datalist = document.getElementById("datalist");
const arr = values.map(k => new Option(k));

let start = performance.now();
datalist.replaceChildren(...arr);
console.log('plain replace:', performance.now() - start);

// reset
datalist.replaceChildren(...[]);

start = performance.now();
datalist.setAttribute("id", undefined);
datalist.replaceChildren(...arr);
datalist.setAttribute("id", "datalist");
console.log('replace with detach and attach:', performance.now() - start);
<input list="datalist" />
<datalist id="datalist"></datalist>

于 2021-12-23T10:56:19.093 回答