本文介绍了在2019年高效地填充Select Elements的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须通过DOM和Javascript动态填充HTML select元素.

I had to dynamically populate an HTML select element via the DOM and Javascript.

我做了一些研究,发现一切正常,但还有其他问题.

I did a little research and I got things working with no problem, but I had some further questions.

我发现2篇关于如何填充选择元素的stackoveflow帖子和另一篇非堆栈博客文章:

I found 2 stackoveflow posts and another non-stack blog post concerning how to populate Select Elements:

所有3篇文章的年龄都在8到10岁之间.由于较旧的浏览器无法使用"innerHTML" DOM属性,因此他们似乎更喜欢下面讨论的某种技术.

All 3 articles are anywhere from 8 - 10 years old. They seem to favor a certain technique discussed below due to older browsers NOT being able to use 'innerHTML' DOM property.

所有这3篇文章均指示使用DOM通过DOM填充选择元素":document.createElement("option").

All 3 of these articles instruct to populate Select Elements via the DOM using:document.createElement("option").

许多人试图使用"Element.innerHTML" DOM属性而不是使用document.createElement("option")来填充具有STRING选项的Select Elements.

A number of people have tried to use the 'Element.innerHTML' DOM property to populate Select Elements with a STRING of options rather than using document.createElement("option").

显然,然后指示这些人使用document.createElement("option")而不是'innerHTML',因为'innerHTML'在Internet Explorer等较旧的浏览器中存在一些已知问题.

Apparently, these people are then instructed to use document.createElement("option") rather than 'innerHTML' beacause 'innerHTML' has some known issues in older browsers such as Internet Explorer.

通常,我不会再对此进行研究,而只使用document.createElement("option"),但是我有2个问题:

Normally, I would not look into this any further and just go with document.createElement("option") but I have 2 concerns:

  1. 我正在填充2个选择元素,每个元素有190个选项(总共380个),每个选项代表一个ISO语言代码.

  1. I am populating 2 Select Elements with 190 Options each (380 total) and each option represents an ISO Language Code.

因此,通过Array.prototype.forEach()的每次迭代,Javscript应用程序将为每种ISO语言代码创建一个对象.总共有380个对象.

So through each iteration of Array.prototype.forEach() the Javscript application is creating an object for each and every ISO language code. That's 380 objects total in memory.

与仅构建一个很大的选项字符串并通过'innerHTML插入'相比,document.createElement("option")效率不高吗?

Isn't document.createElement("option") inefficient when compared to just building a very large String of options and inserting via 'innerHTML?'

我已经在最新的Chrome和Firefox浏览器中测试了"innerHTML"方式,并且效果很好.

I have tested the 'innerHTML' way in the latest Chrome and Firefox browsers and it works fine.

我无意支持Internet Explorer等较旧的浏览器,因此"innerHTML"在我看来是否可行?

I have no intention of supporting older browsers such as Internet Explorer so is 'innerHTML' a viable option in my case?

我真的很想使用"innerHTML",因为代码更具可读性(并节省了内存?):

I would really like to use 'innerHTML' as the code is so much more readable (and saves memory?):

Array.prototype.map().toString 给了我完整的选项字符串.

Array.prototype.map().toString gives me the full String of options.

任何对此事的想法将不胜感激.

Any thoughts on this matter would be greatly appreciated.

推荐答案

正如@Tibrogargan正确指出的那样,在尝试优化之前,应在要支持的最慢设备上进行测试.在便携式计算机上,在15毫秒内处理了 10,000 个选项,如果您关心资源非常有限的设备,那么可以说应该将其作为HTML页面的一部分,而不是运行JS ...

As @Tibrogargan rightly notes, before trying to optimize you should test on the slowest device you want to support. On a laptop 10,000 options are processed in 15 ms, and if you care about very resource constrained devices, you arguably ought to serve this as part of the HTML page instead of running JS...

与建立DOM和创建用于设置innerHTML的字符串相比,我认为DOM的方式在以下方面并不会比innerHTML差,甚至可能更好:

Comparing building up the DOM vs creating a string to set innerHTML, I think the DOM way is not any worse and possibly better than innerHTML in:

  • 创建的对象数量: document.createElement("option")(或 new Option())创建DOM节点,这些节点是也是在设置 innerHTML 时创建的!您可能会争辩说,这还会创建不必要的DOM对象的JavaScript包装器/表示形式,但是使用 innerHTML 时,您正在创建许多临时字符串,并且不清楚哪一个更糟.
  • 可读性:使用 new Option(label,value)可以说比连接HTML字符串(< option value ='" + value+'>" + ... ),尽管如果您使用模板文字我会说这两种方法彼此相同.
  • 众所周知,
  • 基准化很难正确执行,但是由于人们喜欢发布jsperf链接,因此这是一个,它显示 new Option()在Firefox中更快(在Chrome中具有相同的性能).我不会声称这是正确的(尤其是我对GC表示怀疑),但是其他基准测试也都没有声称innerHTML更快.
  • The amount objects created: document.createElement("option") (or new Option()) creates DOM nodes, which are also created when you set innerHTML! You might argue this also creates unnecessary JavaScript wrappers/representations of the DOM objects, but with innerHTML you're creating lots of temporary strings, and it's not clear which is worse.
  • Readability: using new Option(label, value) is arguably more clear than concatenating the HTML string ("<option value='" + value + "'>" + ...), though if you use template literals I'd say the two methods are on par with each other.
  • Benchmarking is notoriously hard to do correctly, but since people like to post jsperf links, here's one showing new Option() being faster in Firefox (and having the same performance in Chrome). I won't claim it's correct (have my doubts about the GC, in particular), but neither are the other benchmarks claiming that innerHTML is faster.

但是我敢于使用一个真实的测试用例,发现一种能够显示出任何可测量差异的设备:

But with a real testcase I dare you find a device that shows any measurable difference:

const labels = [...Array(1000).keys()].map((i) => Math.sin(i+1).toString(36).substring(2)); // random looking strings
const div = document.getElementById("container");


function timeIt(fn) {
    let start = performance.now();

    fn();

    let elapsedMS = performance.now() - start
    div.innerHTML = "";
    return elapsedMS;
}

function createUsingDOM() {
    let select = document.createElement("select");
    for (let i = 0, len = labels.length; i < len; i++) {
        select.appendChild(new Option(labels[i], i));
    }
    div.appendChild(select);
}

function createUsingInnerHTML() {
    let options = [];
    for (let i = 0, len = labels.length; i < len; i++) {
       options.push("<option value='" + i + "'>" + labels[i] + "</option>");
    }
    div.innerHTML = "<select>" + options.join("") + "</select>";
}

//createUsingDOM()
// createUsingInnerHTML();
alert(`DOM: ${timeIt(createUsingDOM)}ms, innerHTML: ${timeIt(createUsingInnerHTML)}ms`)
<div id="container"></div>

这篇关于在2019年高效地填充Select Elements的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 04:56