0

Image we have a form with a button to make table rows randomly rearrange every second, and a button to sort rows based on some criteria.

I made one example here https://codesandbox.io/s/dawn-water-l2m7g without using any JS libraries.

The way I rearrange the rows in the form is to manipulating the JSON object and regenerate the dom element as a whole

let list = TABLE_DATA; // from the JSON file
...

function startRandom() {
  timer = setInterval(function() {
    list = list.sort(randomSort);
    renderList(list);
  }, 1000);
}

function renderList(list) {
  const res = list
    .map(item => {
      return renderRow(xssFilter(item));
    })
    .join("");

  tbody.innerHTML = res;
}

function renderRow(item) {
  return `
    <tr>
        <td>${item.id}</td>
        <td><img src="${item.thumbnailUrl}" /></td>
        <td>${item.name}</td>
        <td>${item.price}</td>
    </tr>
    `;
}

This website works, but I guess every time renderList is invoked, the whole tbody is going to be destroyed and recreated again. Not good performance-wise.

I hope someone can take a look at it and make some optimizations based on the functionalities it has now. For example, maybe DocumentFragment can help. But I'm not sure.

I don't have much experience dealing with front end development but I feel like this example is not uncommon so I really want to know what is the best practice here and how can we make it better.

Joji
  • 4,703
  • 7
  • 41
  • 86
  • We don't typically ask for suggestions or ask for others to write code for us. You know what the problem, you have to try something. See https://stackoverflow.com/questions/14267781/sorting-html-table-with-javascript Not having experience with front-end development doesn't excuse you from doing your due dilligence. – Ruan Mendes Mar 03 '20 at 05:24
  • OP is not asking "write this code for me", he's asking for how the problem can be *approached*, which is pretty different and is fine for a question – CertainPerformance Mar 03 '20 at 05:29
  • @CertainPerformance The only way to answer the OP's question is through a comment showing code or by actually implementing it in an answer, isn't it? The OP did not show that they even tried it. I did link to an existing answer. OP said: `I hope someone can take a look at it and make some optimizations based on the functionalities it has now.` That's asking to rewrite his existing code. – Ruan Mendes Mar 03 '20 at 05:30
  • 1
    Tables and TBodies have a *rows* collection that can easily be re-ordered by assignment. Create an array from the table's rows, then just assign to `table.rows[i]` or `tbodies[n].rows[i]` as appropriate. – RobG Mar 03 '20 at 05:30
  • 1
    @JuanMendes While a live demonstration is often *helpful*, it's not essential. If this hadn't been a duplicate, an answer of, eg, "Sort an array of indicies, then use `appendChild` for each row" would have been decent. – CertainPerformance Mar 03 '20 at 05:32
  • @CertainPerformance Yeah, and that would belong in a comment not in an answer which I was about to explain but realized it had already been answered. One should at least search before asking. – Ruan Mendes Mar 03 '20 at 05:33
  • @JuanMendes I don't know how you came to that conclusion that I didn't try before asking. I tried to use `DocumentFragment` but I didn't see significant performance difference by using http://jsperf.com. Also my question is more than how to sort the table. I know how to sort the table. The link you pasted here doesn't solve my question. Why can't you just leave my question here and let people who happens to know front end optimization and have time so they can give a couple suggestions. I spent a lot of effort to make the exmaple. Now Can you please reopen this question or I will go a new one. – Joji Mar 03 '20 at 05:59
  • Having one "destroy all" and one "rebuild all" might actually be better than having 30K "move one". Your logic seems ok. You may want to pre-parse all the data so things like sanitization is done only once, but I guess that will be only minor. IMM, the only real big performance improvement you could get with such a project would be to implement pagination to your table, so that you show only 50 rows at max every time. – Kaiido Mar 03 '20 at 06:23
  • @joji You didn't post what you tried, which is required. See https://stackoverflow.com/help/how-to-ask. The linked question does show what to do, you move the TRs by calling tbody.appendChild on all rows in the order you need it. Please do post a new question showing what you have tried. – Ruan Mendes Mar 03 '20 at 11:37
  • @kaido Rebuilding the entire table is slower, and also loses any state you may have in those rows, for example, if there were checkbox that were checked – Ruan Mendes Mar 03 '20 at 11:40
  • @joji Your new question should explain why the linked question doesn't answer it. You probably noticed that though others disagreed on whether your question was properly asked, they did not disagree that it was a duplicate. – Ruan Mendes Mar 03 '20 at 12:55
  • See https://jsfiddle.net/mendesjuan/g0zrk6tx/ for a simple example, note that it follows the same pattern as the linked answer except that it uses `append` instead of `appendChild` for performance reasons. Get list of rows; Sort rows as needed, insert them back into the table. – Ruan Mendes Mar 03 '20 at 15:43
  • @JuanMendes any proof that "it's faster"? Remember I talked about 30K rows, not 3 rows. For your state thing you should anyway have it in your js data structure and not rely on the DOM status, that's not a valid point either. – Kaiido Mar 04 '20 at 02:19
  • @kalido common knowledge is that reordering the rows is faster, the onus is on you to prove otherwise, that example is just to show the OP – Ruan Mendes Mar 04 '20 at 12:42

0 Answers0