7 ms·
innerHTML doesn't preserve event handlers. So you're either reassigning event handlers over and over or relying on delegate handlers everywhere. And while your
by ttfkam 4y ago
innerHTML doesn't preserve event handlers. So you're either reassigning event handlers over and over or relying on delegate handlers everywhere.
And while your statement makes intuitive sense regarding performance, actual measurements show clearly that idiomatic Svelte (and other modern frameworks) routinely beat VDOM-based efforts handily in their idiomatic cases and often even when folks jump through the performance optimization hoops needed for VDOM.
VDOM is pure overhead. Better than manually aligning writes before reads manually a la 2010, but noticeably worse than the current crop of compiled offerings.
- c-smile 4y agoIt depends how really you use virtual DOM. React's "reconciliate whole world" approach can be excessive, yes. But, for example in Sciter, vDOM works in [web] component cases that are similar to Svelte: class Beers extends Element { bottles; render() { return <span .bottles>{this.bottles}</span> } set value(v) { this.componentUpdate({bottles:v}) } } When you will do document.$(".bottles").value = 12; it will update only what is needed. Pretty much Svelte style but with the convenience of vDOM.
- c-smile 4y agoTo make it even closer to Svelte, Sciter has native signal() implementation, so let bottles = signal(0); function Beers() { return <span .bottles multiple={bottles.value > 1}>{bottles.value} bottles of beer</span> } document.body.append(<Beers/>); That can be updated by simply changing signal: bottles.value = 42; // Party time! Note: this does not require any preprocessors or precompilations.
- ttfkam 4y agoLet's compare lines of code, because more lines invariably leads to more bugs. Contents of Beers.svelte: <script> export let bottles = 99; </script> {#if bottles > 0} <span class="bottles" on:click={() => --bottles}> {bottles} bottles of beer on the wall </span> {:else} <span class="bottles"> No more bottles of beer on the wall </span> {/if} Then to use it: <script> import Beers from './Beers.svelte'; </script> <Beers /> No knowledge of Reactor's existence needed let alone the library's "signal" function. No functions needed at all. No bespoke syntax for the "bottles" CSS class. No vDOM API call. No extra "values" accessing property. It's >90% plain old HTML, CSS, and JS with literally the bare minimum of syntax to handle data binding. Yes, it requires a compiler, but I would honestly astounded if you even noticed the compiler build time in dev mode. AND the deployed code is smaller. AND it's simpler for the dev to understand and maintain. AND it's likely faster at runtime. The argument that Svelte adds mental overhead is manifest nonsense. If you like the vDOM, have at it. Follow your bliss. Some folks like hitting and kicking trees. Some folks prefer their coffee too hot to drink. I for one want a web framework that makes web development as simple, straightforward, and powerful as possible. HTML, CSS, and the smallest amount of JS and HTML annotation imaginable.
- c-smile 4y agoIn Sciter you do not need any preprocessor at all, not even JS in your HTML: <style> div.beer { prototype: Beer url(/components/beer.js); } </style> <body> <div class="beer" /> </body> After that div.beer element will be instanceof Beer. In this case class Beer used as a [Web-alike] component.
- ttfkam 4y ago1. I think you accidentally a <style> tag 2. Your example would have atrocious load time implications for any non-trivial web page. Iterating the DOM through querySelectorAll to replace items at load time? Yikes! So apparently with Sciter you can either have minimal code or acceptable performance. Got it. Would rather have my cake and eat it too.
- c-smile 4y agoMy sample is correct. CSS prototype property is a Sciter specific extension. When the engine computes styles it does [if needed] this (pseudocode): Object.setPrototypeOf(element, thatClass); element.componentDidMount(); on applied elements. There is no "performance sacrifice" in case of handling prototype properties. Prototypes are switchable if needed: div.beer { prototype: Beer url(...); } div.beer:hover { prototype: BeerHovered url(...); }
- ttfkam 4y agoOh geez. It's Internet Explorer CSS Behaviors all over again. "Those who do not learn from the past…"
- c-smile 4y agoClose but not exactly, there is no esoteric HTC stuff for example. element.selector { prototype: ClassName url(in-module.js); color: blue; ... } That above is significantly better than almost-dead-at-birth WebComponents: let customElementRegistry = window.customElements; customElementRegistry.define('my-custom-element', MyCustomElement); One simple CSS property instead of 20+ additional entities https://developer.mozilla.org/en-US/docs/Web/Web_Components https://developer.mozilla.org/en-US/docs/Web/Web_Components Used quite a lot actually, on half of machines where Sciter is installed (~500..600 mln machines :)
- szastamasta 4y agoFrom what I know React does not register event handlers on individual nodes, but rather on root component. Then it uses virtual events from it’s pool in your callbacks.
- kamikaz1k 4y agoWow, I didn't know this! All that Synethetic stuff makes sense in retrospect... I tried a quick google and didn't find any articles discussing it directly. Do you have any links to offer? Thanks in advance!
- szastamasta 4y agoCannot find a page about it in the docs, but here they discuss how it was changed from document root to React root in React 17: https://reactjs.org/blog/2020/08/10/react-v17-rc.html#changes-to-event-delegation https://reactjs.org/blog/2020/08/10/react-v17-rc.html#change...
- matvp 4y agoSide note, synthetic events are no longer pooled since React 17. There's no longer a noticable performance gain with more modern browsers nowadays.
- zozbot234 4y agoElement.insertAdjacentHTML() appears to fix the event handlers issue (and similar issues with element state), since unlike innerHTML it does not replace the element it's being used on.
- c-smile 4y agoAgain, in case of Sciter, event handlers are not the problem at all as it supports declarative event handlers: class FooBar extends Element { render() { return <form.foobar> <button.foo>Foo</button> <button.bar>Bar</button> </form> } // event handlers: ["on click at button.foo"](evt,button) { console.log("click on button foo") } ["on click at button.bar"](evt,button) { console.log("click on button bar") } } document.body.append(<FooBar />); This approach will define event handlers on the class rather than on individual element. And there is a slight difference between Sciter's components and React ones. Sciter component is real DOM element: const foobar = document.$("form.foobar"); foobar instanceof FooBar; // true That allows to use JSX/vDOM as Web Components as React Components - bests of two worlds.
- ttfkam 4y agoI swear, folks and their JSX have me convinced they have Stockholm Syndrome. HTML+CSS in JS was always a pragmatic choice back in 2015, never the most elegant or most maintainable one. It's like the folks who refused to use anything but the DOM APIs when JQuery was sitting right there. Or who keep on using onclick handlers on their div tags instead of using perfectly good HTML tags like: <a> <button> <input type="submit"> <details> JSX was never the best of any web development world. It was at best the least worst option at the time. We have better ones now.
- RussianCow 4y ago> We have better ones now. Would you mind elaborating on what the better options are? The way I see it, there are a few possible alternatives: 1) Keep the same runtime DOM representation but use normal JS (something like `div({className: 'beer'})`). I know some people disagree, but I strongly believe that this is strictly worse than JSX because it's more verbose and far less readable. 2) Use string templates parsed at runtime. You lose most of the structure you get with JSX—static syntax checking, type safety, autocomplete, etc. Composition becomes a matter of string concatenation, which is possibly the worst way to do it. On top of that, you have to learn templating primitives specific to your templating library instead of being able to simply use what you already know: JavaScript. 3) Use templates parsed at compile-time. This removes most of the drawbacks of #2, but you still have to learn a new templating language and all of the idioms that come with it. On top of that, you're entirely dependent on IDE integration for syntax highlighting and autocomplete. (I realize that JSX has the same problem with custom syntax, but the tooling around it is ubiquitous by now.) You could make a strong case for #3 being a good way to do templating, but there is no "best" or "most maintainable" option; there are only tradeoffs. JSX happens to have a really good set of tradeoffs going for it, and no one has (yet) created anything that's strictly better.
- scotty79 4y agoinnerHTML can set event handlers so you don't have to assign them separately. And if you re-create dom fragment with innerHTML you can reattach children that didn't change and their handlers are preserved.