Have you heard of hyperapp? From the official [0][@hyperapp/html]:
import { app } from "https://unpkg.com/hyperapp";
import {
main,
h1,
button,
text,
} from "https://unpkg.com/@hyperapp/html?module";
const Subtract = (state) => ({ ...state, count: state.count - 1 });
const Add = (state) => ({ ...state, count: state.count + 1 });
const page = ({count}) =>
main([
h1(text(count)),
button({ onclick: Subtract }, text("-")),
button({ onclick: Add }, text("+")),
]);
app({
init: (count = 0) => ({ count }),
view: page,
node: document.getElementById("app"),
})
I can't imagine building anything anymore with the overly verbose bloat that is React.[0]: https://github.com/jorgebucaran/hyperapp/tree/main/packages/...
I'm experimenting with recreating the whole DOM tree like this:
function render() {
restoreFocus(() =>
document.body.replaceChildren(App()))
}
function App() {
return (
createElement('div', { className: 'App' },
createElement('h1', null, 'Hello, World')))
}
function createElement(tag, props, ...children) {
const elem = document.createElement(tag)
for (const [k, v] of Object.entries(props || {}))
if (k === 'ref') v.elem = elem
else if (k === 'style') Object.assign(elem.style, v)
else if (k.startsWith('on')) elem.addEventListener(k.slice(2).toLowerCase(), ...[v].flat())
else if (k in elem) elem[k] = v
else elem.setAttribute(k, v)
elem.append(...children.flat().filter(Boolean))
return elem
}
`restoreFocus` is here:https://github.com/ericfortis/mockaton/blob/main/src/client/...
Results so far:
Rendering the whole DOM tree (instead of VDOMs) is a fast process. The slow part is attaching (committing) elements to the doc. For example, I have a test of 20,000 elements which takes <30ms to render, while attaching them takes 120ms.
Since the performance is mainly bound to the commit phase, with a DOM merging library, or hopefully, if we get a native API such as `document.replaceChildren(...App(), { merge: true })`, this approach could be better.
Caveats:
Although it restores focus, that's not the only thing we need to preserve, we also need to preserve scroll position and cursor position.
So to work around that, I still have to step out fully declarative, by just replacing the part that changed. For example, here I had to do manually mutate the DOM:
https://github.com/ericfortis/mockaton/blob/main/src/client/...
For the life of me I don’t understand why people absolutely insist on using JavaScript to render HTML. Backend frameworks do HTmL just fine.
DOM manipulations can be simplified to just a few actions: remove, Add, change.
The other types of manipulations and interactive features can be sprinkles of JavaScript instead of hundreds of kilobytes of the stuff.
HTMX, Hotwire/Turbo, LiveView are just so much saner to me.
I ask a LLM to do it :'(
This is a really weird website, I glanced over a bunch of different articles and all read like AI slop to me.
Indeed, a detecting tool like GPT Zero is "highly confident" that 97% of this article is AI generated, while AI Detector returns "We are 100% confident that the text scanned is AI-generated".
Curious if this is an uncanny valley situation, because there aren't that many tells (dashes, etc.) in the text itself. Does it feel the same to you?
[dead]
There are a bunch of utilities that don't actually _do_ anything useful. The proxy in this example is used for nothing other than debug logs. The DOM utility layer just slightly reduces the number of LOC to create a DOM node.
And then you end up with consumer code that is not actually declarative? The final code still directly manipulates the DOM. And this shows the simplest possible example - creating and removing nodes. The difficult part that libraries/frameworks solve is _updating_ the DOM at scale.