5 ms·
Sadly, it seems like nobody is considering the best optimization: make DOM operations fast. I think if you could batch DOM operations together you could avoid a
by overgard 4y ago
Sadly, it seems like nobody is considering the best optimization: make DOM operations fast. I think if you could batch DOM operations together you could avoid a lot of wasted relayout and duplicate calculations.
- msoad 4y agoYou can't parallelize DOM updates. All has to happen in the main loop. This is not gonna change for the web as it is today.
- afavour 4y agoI don't think that's what OP is saying. They're saying that (e.g.) calculations are made on each appendChild() call when it would be more efficient (when you know you're going to be inserting a ton) to suspend all calculation, insert 1000 nodes, then resume calculations. Something akin to setNeedsLayout() on iOS: https://developer.apple.com/documentation/uikit/uiview/1622601-setneedslayout https://developer.apple.com/documentation/uikit/uiview/16226...
- nickpeterson 4y agoI good parallel might be database development, the difference between taking a cursor and looping through to make changes vs a set based operation that understands how to specify all the needed changes at once.
- overgard 4y agoYes, that's exactly my point, thanks for expressing it better than I could
- overgard 4y agoMy point is that if you change the DOM api itself thats the win. Right now its just individual property updates, so the browser can't know when to delay a computation. So definitely not part of the web today, but it seems worth considering.
- afavour 4y agoAgreed, I'd love to see HTMLElement.beginTransaction() or something similar.
- thomasikzelf 4y agoDocument fragments are like transactions for the DOM. Alternatively you could just learn which Dom operations force a layout shift and batch those.
- overgard 4y agoYou are correct, but if you think about it, you're talking about parsing and tokenizing before the operation can even occur. That's really heavy. I think it could be better than reading .innerHTML
- masklinn 4y ago> Document fragments are like transactions for the DOM. About the same way innerHTML is which is completely unhelpful: during reconciliation you need to copy, update, and reset the subtree which contains all the update points, which is almost certainly a lot more than you need. You also likely need to reconcile document state (e.g. focus) by hand.
- c-smile 4y agoI was thinking of how to improve DOM updates. One of ideas is to add Element.update() method: Element.update(function(updateCtx) { updateCtx.setInnerText(this, "new text"); updateCtx.setAttribute(this, "title", "new title"); ... }); This has two benefits: 1) transactional update, 2) for contenteditable scenarios it can group DOM mutations in atomic undo-able action. But I've discarded that in lieu of Element.patch(vDOM): Element.patch(<div title="new title">new text</div>); as the later is more humanistic I would say.
- overgard 4y agoI actually think the former example is more clear. It's a bit verbose but every part is simple. The second example is very "magic", it takes a lot of thought to understand
- yuzuquat 4y agoMy feeling is that the browser already does this in that it considers all DOM apis within a single 16ms (requestAnimationFrame?) as a single transaction. The trouble for browsers, is if certain DOM apis have a dependency on the layout of another element. My naive and unvalidated understanding: // Good: These DOM calls in a single frame will trigger layout-paint-composite (1 loop) - e.style.backgroundColor = "red"; - e.style.width = "20px"; - e.style.transform = "translateX(10px); // Bad: These DOM calls in a single frame will trigger layout-?-layout-paint-composite (2 loops) - ... - e.style.height = otherElement.offsetWidth + 200 + "px" - ... The reason being that without knowing the width of "otherElement", there's no way for the js runtime to execute the "e.style.height" line and execution needs to be paused while layout occurs. If you're looking for a transactional syntax (similar to what you've proposed) that also addresses this though, fastdom looks like a good option: fastdom.mutate(() => { element.style.width = "20px" }); I'm not a browser expert though so if I"m misunderstanding something, would love to know.
- boomlinde 4y ago> Sadly, it seems like nobody is considering the best optimization: make DOM operations fast. On the contrary, there is evidence that quite a few people are considering that.
- overgard 4y agoWell, slight amendment: Lots of people want to make the current api fast, but it seems there's little movement on a new api.