which ends up being a sequence of in-place string appends.
In any good implementation, a sequence of repeated appends takes linear time in the total length of all the appended strings, like join('').
I've just tested this theory in Safari 14.0.2 with a JS console one-liner. On this browser, both versions take linear time not quadratic, and the test corresponding to the first version even runs slightly faster.
The time difference is small though, and you're right, the second version is explicitly linear time. If I had tested with a much older browser (maybe IE8), I think the first version would have taken quadratic time.
It could be an issue for websites with huge audiences and many comments, but I (guess) this wouldn't be a big performance issue for most personal static websites. Probably, the audience size and number of comments is not big enough to cause any trouble.
Your alternative is also pretty bad as it will generate lots of intermediate Strings before joining them up...
Just use a forEach instead and append directly to the DOM:
let root = document.getElementById('mastodon-comments-list');
data['descendants'].forEach(reply => {
let div = document.createElement('div');
div.innerHtml = DOMPurify.sanitize( ... );
root.append(div);
});
"Pretty bad" is unwarranted in my opinion. Your alternative adds overhead of creating an extra div for each intermediate string in the code it replaces. It's trivial overhead, and may be a small number, but exactly the same applies to the overhead of temporary strings - they are comparable.
Intermediate string length doesn't matter for time complexity here. If they are short they will be fast. If they are long, the time to scan and parse in DOMPurify and innerHTML will dominate.
After building the DOM, your extra divs are processed every time that section of the DOM is styled and rendered, not just once. If the number of extra divs is low enough that this is negligible, so is the number of intermediate strings in the alternative code.
So I wouldn't assume your version is faster at setting up, and it may be marginally slower later on repeated renderings. I'd profile both versions, maybe with Browserscope (which probably has a test for this particular question already).
However if I couldn't profile and was asked my guess at the fastest version, my guess is the string-join version. I'd be more concerned with whether concatenating DOMPurify.sanitize() strings is guaranteed to maintain the same security properties.
If anyone wanted to provide half useful bikeshedding, they could make the "Load Comments" button disable and change to "Loading..." while it's being fetched. Right now there's no feedback and the user is likely to click multiple times wondering if it's working on a slower connection like mine.
They could also probably just html-escape the few foreign values rather than bringing an HTML parser to the entire template.
Are you serious? The intermediate strings are comments to a blog post... putting them all into Strings then joining them all up means you'll have huge amount of RAM being consumed for no reason. Updating the DOM as soon as you get the information is optimal for memory utilisation and for user feedback, which are more important than the total time (even if the total time is longer, which I doubt because if there's a large number of replies, most of them won't be visible in the viewport and hence should be very cheap too.
Yes I'm serious. The intermediate string's RAM is automatically much smaller than the RAM consumed by the DOM and the calculated box model and text layout graph, so its size is insignificant. If it's huge, you have much bigger problems from the DOM. Also, the intermediate string is temporary, and will be freed after the DOM is created but before the box model and text layout graph is allocated and calculated, so it might not end up using any extra RAM at all.
In this example, updating the DOM as soon as you get the information is not optimal for user feedback, because rendering is paused until after all the DOM updates anyway. DOM rendering in all modern browsers is lazy. It only starts after JavaScript returns from handling the current event queue.
I doubt it very much. The user will see nothing until all your Strings are in memory (taking up unnecessary RAM). Update the DOM and it will be instantaneous (most of it probably won't be visible in the DOM, so likely to be very cheap as well).