4 ms·
Web Components are damned awkward because they extend the damned awkwardness of the DOM rather than address it. DOMNodes are these hot data structures when the
by EdSharkey 10y ago
Web Components are damned awkward because they extend the damned awkwardness of the DOM rather than address it.
DOMNodes are these hot data structures when they're linked into the DOM tree. Writing (and even sometimes reading) from DOMNodes can cause whole page reflows or paints to occur, sometimes synchronously. The advice to "touch the DOM as little as possible" stems from the fact that the DOM has so many performance pitfalls.
The DOM is so damned awkward that it's faster to maintain a virtual DOM tree, diff changes to it on the next tick with those of the previous, and then only modify the real DOM tree with those changes like React does. Couple that to the fact that React's DOM update strategy is tuned for speed and they can hide/handle most weird DOM object creation/insertion rules, and overall you wind up with a less awkward system.
If I compose my page entirely out of Web Components, the chief benefit I see is good looking markup representative of what's on the page.
If I were to have designed a component system from DOM, I would have added a lightweight iframe-like tag that could be instantiated from a script/css/markup template package. Performance-wise, I thought that having a nested element's box be laid out and painted independently from the parent page could mitigate some of the global ripple effects of touching the DOM. Of course, this lite iframe's box itself would need to live in the parent page and its dimensions would have to factor into the page flow, and that could have global effects. I suspect there could be clever JavaScript or event system additions that would help limit the reflow and paint damage there.
- Touche 10y ago> The DOM is so damned awkward that it's faster to maintain a virtual DOM tree, diff changes to it on the next tick with those of the previous, and then only modify the real DOM tree with those changes like React does. Sorry, but it's not. I don't know what it is that you think React does, but it makes those same awkward DOM API calls. React is an abstraction layer and abstraction has a price. Having React call .appendChild is not faster than you calling .appendChild yourself.
- jakelazaroff 10y agoThe strength of using a virtual DOM as an abstraction isn't that you get around making DOM API calls, but that you can easily batch and sequence them to eke out the best performance. To use your .appendChild example: if you iteratively call .appendChild the browser has to reflow every time that happens, whereas if you know you have a bunch of elements to add you can use another strategy (like document fragments) to do that manipulation all at once. Yeah, you can do this all on your own, but you get it with React for free. Abstraction does not necessarily have a price.
- Touche 10y agoI wasn't judging virtual DOM has wholly good or wholly bad, just pointing out the often incorrect belief that some how React does a magical thing that you are unable to do yourself. Batching, etc. is no different. The advantage in the abstraction is that it makes it a bit easier to maintain, not that its faster.
- bzbarsky 10y ago> if you iteratively call .appendChild the browser has to reflow every time that happens No, it doesn't. Not unless you do one of two things: 1) yield to the event loop and wait for a refresh tick or 2) query layout information. The usual perfomance cliff is when you do #2 interleaved with appendChild. Because then the browser really does need to reflow. With React, what you get is the ability to queue up all your appends but keep asking for the _old_ layout information, without taking your appends into account. Sometimes that's what you want, sometimes it's not. It really depends on why you're asking for the layout information.
- sametmax 10y agoIt is not for small changes. But as soon has you update a whole layout of many listings, I doubt you are manually diffing your nested data structure to produce the less possible updates. React also uses a couple of other tricks, like attaching one event handler to the top of the DOM doc and fire fake events (they call it synthetic) to avoid having many handlers in the page. Or queueing udpates and merging them so that if many updates arrive at a very close time, you update only the DOM once. Vue.js and Angular 2 do the same. Although Vue.js is my favorite right now because it's so much more flexible and easier to use.
- EdSharkey 10y agoI get that. It's why I mentioned "next tick" to indicate the changes are minimized to the diff'd elements and batched. As you say, one can rig up DOM updates through VanillaJS calls that are more efficient than React if you're a clever masochist. If sub-optimal accesses to the DOM is where most of the time is spent in an application, then using an abstraction like React to manage the DOM really can make the system faster AND more manageable, as you say.
- Hurtak 10y ago> The advice to "touch the DOM as little as possible" stems from the fact that the DOM has so many performance pitfalls. What are those performance pitfalls? The only ones I know are that if you read something related to the layout size (offsetHeight), it might cause layout recalculation. And obviously if you modify how element looks like (innerHTML, changing class, etc). This doesn't seem like much (assuming I dit not forget something). The first one is not obvious through.
- jakelazaroff 10y agoOne more pitfall: if you add or remove elements, it also causes a reflow. A common pitfall with applications that render lists is that they do append operations iteratively (with a reflow for each iteration) rather than in one go (with only one reflow). http://jankfree.org/ http://jankfree.org/ is a good resource for causes of slowdown.
- EdSharkey 10y agoI believe this is the comprehensive list: https://gist.github.com/paulirish/5d52fb081b3570c81e3a https://gist.github.com/paulirish/5d52fb081b3570c81e3a My favorite of the doozies is _reading_ from some properties on mouse events will cause a reflow.