I also would have sworn up and down that using a DocumentFragment would be loads faster than both, but it doesn't seem to be the case. I wonder why that is.
Seems like Safari has quite naive element.append(...list) implementation and/or "destructuring to argv" operation is slow there.
I suspect that element.append(...list) is just a
for(auto arg : args)
element.append(arg);
so no transaction there at all - slower version of case #3.
On Windows I am testing it in Edge, Chrome and FF.
Edge and Chrome show close numbers (#1 fastest). FF shows #3 is faster - same problem as Safari I think.
I'd be interesting in learning the answer here as well. I've read that documentFragment are faster, but some microbenchmarking on chrome/mac makes me think either the improvements are negligible. Rerunning benchmarks on stackoverflow (https://stackoverflow.com/questions/14203196/does-using-a-do...) (both individually and swapping the order of fragment vs non-fragment tests) nets me ~60ms when rendering 100000 ul in each case.
My naive take on this is that browsers have overall gotten a lot more consistent with the layout-paint-composite loop, and it's not worthwhile to swap out all your appendChild calls with fragments. On the other hand, making sure your all your layout reads (.clientWidth) are batched before the layout writes (appendChild) is much more important (fastdom)
edit: something like documentFragment/append(...children) would help guarantee the layout trashing addressed by fastdom
When I manipulate the DOM I try to create the entire structure in a fragment and the use .append(...) only once.