I have an empty ul in html and everytime I add or remove a color I call ShowColors which adds li items via JavaScript using .innerHTML. How can I optimize this code without using .innerHTML?
const colorList = document.querySelector(".all-colors");
function ShowColors() {
colorList.innerHTML = savedColorsArray.map(color => `
<li class="color">
<span class="rect" data-color="${color}" style="background: ${color};"></span>
</li>`).join("");
};
<ul class="all-colors"></ul>
I tried .insertAdjacentHTML but I would have to change how the code works to save each element so I can remove it later and also probably have to save it to localStorage so it’s persistent.
savedColorsArray.forEach(color => {
colorList.insertAdjacentHTML('beforeend', `<li class="color">
<span class="rect" data-color="${color}" style="background: ${color};"></span>
</li>`);
2
Answers
.innerHTML
should be avoided whenever possible because calling it invokes the HTML parser, which rebuilds the DOM with the new content, so there are performance implications to using it.While the DOM is being rebuilt with new content, it’s very easy to wipe out previously added event handlers, so there is an opportunity to introduce bugs.
It is well known that using
.innerHTML
can potentially open up a security vulnerability in code as well, when the string that is passed to it is not 100% within the control of the developer.From MDN:
So, the moral of the story is, only use
.innerHTML
when you have no other choice. Fortunately, there often are other choices, the first among them being to create new DOM elements, configure them, and then attach them to the DOM.Here’s how that is done:
A modern approach could be a reactive solution with
Proxy
:you just modify an array of colors and the list is updated automatically.
You just iterate the color array and try to reuse existing
<li>
. If there’s a<li>
with the same index as a color, update it withdataset.color = color
andstyle.background = color
. Otherwise create an<li>
withinnerHTML
like you did. The reusing of DOM elements seems like optimization like you requested.