hyperHTML: updating a list

210 views Asked by At

When I inspect the html elements created by the following code (using hyperHTML in Chrome, the entire list refreshes (I am assuming this based on all elements in the <ul> flashing purple briefly).

function updateList(render, mydata) {
  render`
    <h1>hi</h1>
    <ul>
      ${mydata.map(x => `<li>${x}</li>`)}
    </ul>`;
}
let mylist= new Array(1000).fill(0).map(() => Math.random());
const render = hyperHTML.bind(document.body);
updateList(render, mylist)
setTimeout((render, mylist) => {
  mylist[2] = "ww";
  updateList(render, mylist);
}, 6000, render, mylist);

Is it actually re-rendering the entire list? If so, how could I improve the performance by only rendering the new change? Is this a valid concern, or am I unneccessarily optimizing?

1

There are 1 answers

0
Andrea Giammarchi On BEST ANSWER

Sorry for the delay (I was on vacation) but the answer is simple: if you provide, as interpolation, an array of strings, you have the equivalent of an unsafe, and always new, innerHTML operation, which is both possible but not suggested.

What you need to do, when you have real world data and items, usually as objects, is to relate each item with the piece of DOM it represent.

This is done with wire(...) which accepts a reference, as object, and optionally an id.

Since the reference must be weak, for memory reasons, to recreate your demo you can relate all items to a single source as list could be, and use each item value as unique id.

const {bind, wire} = hyperHTML;
function updateList(render, mydata) {
  render`
    <h1>hi</h1>
    <ul>
      ${mydata.map(
        x => wire(mydata, ':' + x)`<li>${x}</li>`
      )}
    </ul>`;
}
let mylist= new Array(1000).fill(0).map(() => Math.random());
const render = bind(document.body);
updateList(render, mylist)
setTimeout((render, mylist) => {
  mylist[2] = "ww";
  updateList(render, mylist);
}, 6000, render, mylist);

You can see above code working in here: https://codepen.io/WebReflection/pen/wEMWGv?editors=0010