W3C

Parts and Template Instantiation

27 October 2020

Attendees

Present
annevk, bkardell, caridy, dandclark, graynorton, hober, jan, justinfagnani, leobalter, masonfreed, plh, Rob Eisenberg, Rob_Eisenberg, Ryosuke, slightlyoff, smaug, yuzhe-han
Regrets
-
Chair
-
Scribe
annevk, slightlyoff

Meeting minutes

GitHub Proposal, Slides

<annevk> Why is AttributePart not a NodePart? It seems the element passed into the constructor is now not exposed anywhere. Or is there a reason for that?

<annevk> (I think I asked the opposite question on the PR, but I'm sorta wondering why that element is not exposed now. Similar thoughts about ChildNodePart.)

<annevk> (Prolly no need to discuss this in this session though.)

<caridy> this is wonderful! big improvement from previous proposal!

rniwa: merged yesterday...Anne reviewed...posting the proposal

rniwa: https://github.com/w3c/webcomponents/blob/gh-pages/proposals/DOM-Parts.md

rniwa: to annevk's point...should inherit from NodePart/ElementPart

Rob: thanks for putting this together; appreciate the effort...reading the spec this morning

Rob: first impression: quite a few unknowns around partial attribute and node updates in the spec.

Rob: my impression was the options presented were clunky and perhaps difficult to work with. Looking at the proposal, also concerned w/ conflation of different concerns. Batch updating vs. location in the DOM

Rob: affecting/mutating those and then cloning notes

*nodes

<Rob> https://github.com/EisenbergEffect/templating-primitives/blob/main/README.md

Rob: lots of things mixed together...I didn't like that...are there lower-level primitives that can be composed?

Rob: alternative proposal: https://github.com/EisenbergEffect/templating-primitives/blob/main/README.md

Rob: can we make "tracking location in the DOM" it's own thing, re-use in different contexts? Can we make DOM Batching something that can be use outside templating concerns?

Rob: something that threw me at first was "part" terminology...focused around batching of updates...maybe template heritage coloured the terminology?

<jan_> https://github.com/EisenbergEffect/templating-primitives/blob/main/README.md

Rob: first impressions, but can we separate out the concerns within this API and modularise?

Rob: haven't looked at framework code I've written to find out if Parts would work...don't think it would reduce our code a ton...an initial concern...lots of objects and how they need to be configured

justinfagnani: thanks for writing up the doc Rob; points out some things that have been considered and we should write up why they weren't selected here. In particular, 2 things: a new node type to represent location...not feasible to make a new tree node type because existing code won't handle a new node type that's also a container node well.

justinfagnani: this is why part isn't in the tree...sort of like range in that it's out of the tree

justinfagnani: turning on batching from a subtree is a

justinfagnani: an idea we looked at in display-locking and transactional DOM. Implementers reflected that it's super hard to do

<annevk> (I can confirm that introducing new node types is hard. ShadowRoot mostly works because it builds on DocumentFragment and even that had a number of problems and that cannot even be inserted really.)

justinfagnani: parts act as a staging ground -- similar to wycats DOMChangeList proposal -- so if it seems like things are conflated there, it may be due to constraints we're dealing with

justinfagnani: on reducing code, may be true that it won't remove. I looked at Lit and it won't remove a lot of code, but will have a big performance benefit. Reduces some tree-walk operations in cloning.

justinfagnani: on ergonomics, brings us closer to ergonomic/fast solution for folks not using a framework at all. Makes hand-written code faster.

caridy: this feels to me to be sat at the right level of abstraction; as justinfagnani said, won't remove a great deal of code for SalesForce, but will help to have atomic updates on the DOM tree.

caridy: we were concerened about the previous propoosal's new syntax and this is step in the right direction for us. Eager to try this out. As justinfagnani said, ember has been looking for these as well

rniwa: to add to justinfagnani's answer is that the way to think about DOMPart is that it's a Range that has the ability to stage changes

rniwa: if we just had a pair of node + prev node, and you wanted to batch, you could have an array of changes you commit later...the benefit here is the list of mutations that you can capture

rniwa: in the past 5 years or so, there have been various DOM batching proposals. One has been a staged DOM update + commit. Then you're making changes but not committing...but what happens when you create a new element? Can you insert children? You pay the cost of creating the elements. If you get previous sibling and you haven't committed...what happens?

rniwa: weird state where you're committing but based on previous DOM state...or you have a parallel API

rniwa: duplicating DOM API...how do you do previous sibling? next sibling? append child?

rniwa: all of these variants have been explored but don't work

jan_: when we get to bikeshedding, it would be adventageous if the name reflected some of the things rniwa referred to...a part is something we already use to refer to CSS part syntax, e.g., so "part" might not be the thing we're looking for

jan_: "range"...a sequence of childrent parts...a "range"...a subset of an attri

jan_: attribute you want to update

jan_: you could call these "updaters"...DOM Updater...NodeUpdater...AttributeUpdater

jan_: one thing I liked about what Rob said was that sometimes you want a reference to a portion of a tree you can get back to after cloning...once you clone it's no longer there

justinfagnani: it's part of this proposal

jan_: I get that...these may be useful just for keeping track of a portion ofa tree after cloning

jan_: this is a superset of that, so I'm for it, but want to recognise the value of being able to keep references to a location in a tree across cloning

Rob: on second look, it seemed this was oriented around edge updates

Rob: ...made me think "templating" "templating"....maybe renaming could go a long way

Rob: I'm not an expert in DOM internals, so if you say creating new node types are a no-go, will trust you...but feel like we need something to deal with places in the DOM

Rob: today we do this with comment nodes which we use as markers to update things...we can't simply mark a location today based on an unexplicit node the user created because they may insert/append nodes around thigns which throw off location tracking

Rob: see value in that on it's own

<annevk> Aren't parts effectively markers though?

Rob: making this more explicit on the nature of batch updates and pulling out <scribe miss>

yuzhe-han: thanks for the feedback; can take up better naming. In terms of location tracking, focusing on an MVP set of features that webdevs can try it out. Location tracking is part of this proposal. When you clone, you get a node and a part (as a list)

yuzhe-han: so it's an essential part of this proposal to handle location tracking. Coming back to batching, it's important for performance. On a first load, we want to allow cloning and update w/ data w/ batching to do fast updates

yuzhe-han: and then we want to allow continuious updates of data

yuzhe-han: for MVP, location tracking is there...batching for perf gain.

<annevk> I'd still like to see some metrics or longer explanation as to why batching helps. Is it really about avoiding the IDL layer? About avoiding mutation events? Something else?

<justinfagnani> anne: should I ask this on audio?

rniwa: it's important to note that loation tracking is that it's node + name. Parts know what's being inserted. Parts don't know what got inserted....if we just extract location tracking (node + previous sibling) and something updates it...and something is tracking location...there's not much there and may not be justified.

jan_: if I've got a child part...even if I'm not using value or commit...and someone is updating the DOM and removes the previous sibling, we'll get updates to refer to the new previous sibling?

rniwa: no, it does not

jan_: so it's not live?

rniwa: no, it's not a live data structure

jan_: so how does this work then? if someone's live updating the DOM, how does this work?

hober: the idea is that you'd use the part API to update the part

justinfagnani: want to reduce the costs associated with live ranges as well

jan_: I didn't get that out of the spec...

jan_: maybe there are reasons it needs to be that way, but I didn't get it from the doc

<annevk> +1 Would love to see that expanded upon, including on how that works if things are in fact mutated.

rniwa: was explicitly called out in old proposal, should be here as well. Sorry for that.

justinfagnani: annevk was asking about performance gains

justinfagnani: expanding the proposal to enumerate the checks that can be skipped or batched would be helpful

justinfagnani: hayato-san isn't here, but was excited about the benefits

justinfagnani: maybe rniwa can talk about perf benfits?

rniwa: avoiding a range-like situation is pretty crucial. Whenever you have a range in the DOM, you have O(K * N) in K ranges and N nodes; it's worse than that too, relative to start-container and end-container. Have to be checked for every range

<annevk> If there's an active selection there would still be ranges, right?

rniwa: it's very expensive as a design. Similar to the static-range API that doesn't update it's endpoints

annevk - yes

<annevk> (that was rhetorical, I'm wondering why ranges are no longer a problem)

<annevk> (sorry for being vague about it)

rniwa: there are ways browsers can optimise updates; whenever a node is inserted or removed, a browser has to update all state to be consistent

(they are a problem, that's what rniwa is saying)

rniwa: checking which child is a child of another...have to update any live nodelist that may exist in dom, e.g. `getElementsByTagName` have to udpate every time a node is inserted or removed. Whenever a modification happens, a browser has to do a lot of housekeeping....the benefit of this API is that the browser can skip that for these udpates

rniwa: also allows all those changes to be batched together, which is a pretty big benefit

<graynorton> But to be clear, the known, existing perf issues with ranges are orthogonal to this proposal, right? The point of discussing in this context is just that we don't want to introduce a similar perf problem with this proposal.

graynorton: yes

smaug: doesn't property part break some of the perf improvements because you may run it between other mutations?

rniwa: for DOM property, we're desinging it so that we batch DOM mutations and then we invoke property updates. We interleave custom element updates and property updates so they happen in order. Core DOM updates batched, then custom element udpates dispatched in order

smaug: presumes no mutation events?

rniwa: yes, to get to the perf benfits we have to assume no mutation events

justinfagnani: was going to say what rniwa said; that's the key performance benefit between this proposal and the last. All property setting is custom elemenet reaction in script anywya

jan_: switching gears; in the components from the library I lead, we have components factored into pieces which update aspects like properties e.g. style or classList

jan_: one bit of code will update style, one will udpate font, etc.

jan_: one thing I won't get out of this as designed is the ability to target pieces of a property like style or classList

justinfagnani: there might be some improvements on PropertyPart we could make to improve this...an extrapolation of CallbackPart on the reaction queue could do that

justinfagnani: a CallbackPart could have special functions to update style and class via CSS OM directly

justinfagnani: our template framework has "directives" and that's where we'd want to plug in those

justinfagnani: in some future work to template instantiation, we might be able to see that partial updates are important for first-class style updates, but until then, Callbacks seem a good way to address that

jan_: is a "custom part" part of this proposal?

justinfagnani: need to discuss. Not clear

Rob: Is there any thinking about whether the part configuration can be serialized?

Rob: In particular for server-side rendering or pre-compilation of templates.

Rob: Seems worth thinking about, even if not for v1.

rniwa: That's interesting.

plh: No time!

plh: next steps?

<Rob> Sorry to toss that out at the end...but wanted to mention before I forgot :)

Han: thanks everyone for the feedback. Different use cases seems pretty positive.

plh: Thanks everyone, done for the day.

<Rob> Great conversation. Love hearing the thoughts of this group.

<JustinRibeiro> Cheers all for the great session and information! Looking forward to this spec moving forward.

Minutes manually created (not a transcript), formatted by scribe.perl version 124 (Wed Oct 28 18:08:33 2020 UTC).