`document.createElement` performance has come a long way in the last few years. The HTML "string" parser is incredibly well optimized in every browser, but the performance difference between smash a string into `innerHtml` and `document.createElement` approaches has shrunk a lot, especially in the time since React started doing so much VDOM work to avoid both tools as much as possible.
The difference shrinks even further with `<template>`/HtmlTemplateElement, its secondary/content `document`s for `document.createElement` and `document.importNode` being faster for cloning+adoption of a `template.contents` into the main document than string parsing.
I've got work-in-progress branch in a library of mine using JSX to build HtmlTemplateElements directly with `document.createElement` and right now `document.createElement` is the least of my performance concerns and there is no reason to build strings instead of elements.
(ETA: There are of course reasons to serialize elements to strings for SSR, but that's handy enough to do with a DOM emulator like JSDOM rather than need both an elements path and a string path.)
The difference shrinks even further with `<template>`/HtmlTemplateElement, its secondary/content `document`s for `document.createElement` and `document.importNode` being faster for cloning+adoption of a `template.contents` into the main document than string parsing.
I've got work-in-progress branch in a library of mine using JSX to build HtmlTemplateElements directly with `document.createElement` and right now `document.createElement` is the least of my performance concerns and there is no reason to build strings instead of elements.
(ETA: There are of course reasons to serialize elements to strings for SSR, but that's handy enough to do with a DOM emulator like JSDOM rather than need both an elements path and a string path.)