3 ms·
I think React is fine, especially when using it mainly for rendering, keeping async stuff out of the components as much as possible. The React API is way nicer
by emmanueloga_ 2y ago
I think React is fine, especially when using it mainly for rendering, keeping async stuff out of the components as much as possible.
The React API is way nicer to construct DOM trees than using Fragments, creating and appending children elements, concatenating strings to produce HTML, etc.
Imagine being able to do this without importing any 3rd party code:
const content = html`<h1 id=hello>Hello world!</h1>`; // New API: html Tagged templates [1].
console.log(content);
// Outputs: { type: 'h1', props: { id: 'hello' }, children: ['Hello world!'] }
document.querySelector("#container").patch(content); // New API: HTMLElement.patch.
I'm sure there are a few more details involved but it sounds like a relatively small addition to the current DOM APIs.
I’m not aware of any initiatives like this currently. WebComponents could also benefit, as building a DOM tree within a class extending HTMLElement is still cumbersome: the WebComponents API doesn't really add anything to simplify DOM handling, which is why libraries like Lit exist.
--
1: Inspired by https://github.com/developit/htm https://github.com/developit/htm
- emmanueloga_ 2y ago... also TFA conflates web application architecture with frontend frameworks, creating a false dichotomy. For instance, I’m building a site that serves static HTML but still benefits greatly from Preact for the dynamic parts. The critique seems focused on SPA architectures heavily based on React, as seen in frameworks like Next.js and Remix. To be clear, I also lean away from that style of web application architecture, but I’m not sure this 20-page article effectively makes the case for simpler alternatives.
- floydnoel 2y agoI thought Next.js and Remix were SSR-based frameworks, both created as alternatives to building a SPA. After the initial "SPA fever" died down, these frameworks cropped up to address the shortcomings of SPAs such as a lack of SEO-compatibility.
- emmanueloga_ 2y agoNext.js and similar tools redefine server-side rendering (SSR) to mean generating HTML on the server using the same code that runs on the frontend, requiring server-side JavaScript and what they call "hydrating" on the client. Next.js and friends are very much SPA frameworks, they just try to address the shortcomings of SPA architecture and in the process introduce a lot of complicated layers. Since the term SSR has been... "repurposed" now, what I was talking about a simpler CGI-style approach—no JavaScript, no async complications like Suspense. Rendering React components server-side often requires special tricks, especially when components interact with DOM APIs or make HTTP calls. As an example, Templ has a detailed guide on using React in a traditional architecture without server-side rendering React components [1]. --- 1: https://templ.guide/syntax-and-usage/using-react-with-templ/ https://templ.guide/syntax-and-usage/using-react-with-templ/
- spankalee 2y agoThere is a proposal for JavaScript-based HTML templates: https://github.com/WICG/webcomponents/issues/1069 https://github.com/WICG/webcomponents/issues/1069
- emmanueloga_ 2y agoThanks for sharing, I wasn't aware of this one. I hope they succeed!
- BeefWellington 2y agoApart from running screaming in the opposite direction from tagged templates for security reasons, I think a more suitable approach (that fits current ECMAScript naming conventions / namespacing) might just be something like: const content = document.createTemplate(`tagged string`).content You can already effectively do this, though you'll have to decide for yourself if putting the following lines of code into a top-level module translates to "Writing your own framework": function html(markup) { const templateNode = document.createElement(markup) templateNode.innerHTML = markup return templateNode.content } Then your code becomes roughly: import html from "MyModule" const content = html`<h1 id=hello>Hello world!</h1>`; // No New API Needed document.querySelector("#container").replaceChildren(content.childNodes) You're losing the pretty printing in the console but there's options for that -- from tweaking the toString() prototype method to straight up creating a custom class that acts as an Element. Worth noting too: you could cheat in the html function above and have it directly return content.childNodes, thus reducing the differences between the two examples to simply "patch" vs "replaceChildren". In your example, are you envisioning that HTMLElement.patch() is doing something different than Element.replaceChildren() or Element.replaceWith()? That'd be one area that wouldn't be addressed with this. Having it first-party would be lovely but it's already pretty doable.
- emmanueloga_ 2y agoAll of what I'm talking about is doable through libraries today (or you can write it yourself). But making things available through DOM APIs create a new baseline where the very same tools are made available for anyone, no matter the framework (think: document.querySelector APIs). Regarding patch, morphdom explains very well the difference between replacing and patching the DOM [1]: > Replacing an entire DOM tree is fast but loses internal state (e.g., scroll positions, input carets, CSS transitions). Instead, we aim to transform the existing DOM tree to match the new one, minimizing changes and preserving state. Also, there's the matter of performance. Diffing and patching as a single method call implemented natively should be a lot faster than using a bunch of JS code. --- 1: https://github.com/patrick-steele-idem/morphdom https://github.com/patrick-steele-idem/morphdom
- 2y ago
- meiraleal 2y agowhat you described is lit-html, which might find its way to the browser: https://github.com/WICG/webcomponents/issues/1069 https://github.com/WICG/webcomponents/issues/1069