You must be familiar with my "React is Junk" series of articles given your attempt to use that shit-show as an insult against my knowledge.
Are you familiar with how date.now() has a granularity limit ranging from 50ms to 200ms depending on browser engine? Have you ever heard of Performance.now() and why it's superior to date.now()?
https://developer.mozilla.org/en-US/docs/Web/API/Performance/now
Are you aware that RAF (requestAnimationFrame) can often fire BEFORE the next render or even the current document parsing stage fires? (since why parse/render before a request that inherently changes the render?)
As to performance differences, your endless nesting of anonymous functions is hobbling nearly every test, but nowhere more so than the DOM/node versions. You've got so much overhead for nothing in your code in terms of functions, variables, and garbage collection it's no wonder all your tests are spitting distance from each-other! Also notice the execution differences of your own tests across the graph!
function row(vals) {
const rowDiv = document.createElement("div");
rowDiv.className = 'row';
rowDiv.append(...vals.map(val => {
const cell = document.createElement("div");
cell.title = val;
cell.append(val);
return cell;
}));
return rowDiv;
}
Is one hell of a shit-show of callbacks and destructuring -- ALL of which add pointless overhead and delays -- for what should likely be just:
function row(...args) {
let rowDiv = document.createElement("div");
rowDiv.className = "row";
for (let value of args) {
let cell = rowDiv.appendChild(document.createElement("div"));
cell.title = cell.textContent = value;
}
return rowDiv;
}
Though I have to wonder why the blazes you'd set title on a DIV. Is that just so you can BS an attribute to add to the parsing overhead? (which... ok, might be a good idea even if it's typically anti-semantic markup)
Destructuring adds overhead in both memory and execution time because you are making new copies, so keep that to a minimum! The generic append is slow and adds execution time because it has to do another extra loop AFTER the extra loop of the garbage map… much less it has to test each of the parameters to see if it’s an instance of Node or not. Creating an entire blasted array of these elements via map -- as const nonetheless -- sucks on memory like candy and adds execution time and garbage collection woes.
Also notice how nice it is to leverage how appendChild (unlike append) returns the appended node. If you weren't setting title you could even get rid of the internal "cell" variable.
All those fancy "new" methods are just clubbing the DOM NODE/Element performance in the kneecap like a 1990's figure skater.