Description
Describe the problem
Until recently, we had an optimisation for each
blocks that were the sole child of an element — we called these 'controlled' blocks, and we could make it faster to empty them by doing element.textContent = ''
.
This optimisation was a casualty of a recent refactor, and should be reinstated. But it shouldn't just apply to each
blocks, it should apply to everything — if
blocks, components, and so on.
Describe the proposed solution
There are four parts that need to work in concert with each other. Firstly, SSR would ideally not bother creating hydration markers — given something like this....
<div><Foo /></div>
...we could just render the <Foo />
contents directly inside the <div>
:
-<div><!--[-->(foo contents)<!--]--></div>
+<div>(foo contents)</div>
Secondly, the client-side component's template would skip the anchor:
-var root = $.template(`<div><!></div>`);
+var root = $.template(`<div />`);
Thirdly, the code that finds the anchor would need to be aware of this situation. The $.anchor
function here (name subject to bikeshedding) would a) populate hydrate_nodes
with the contents of the <div>
during hydration, b) insert an empty text node at the end of the <div>
and c) return that empty text node to use as the anchor for <Foo />
:
var div = root();
-var node = $.child(div);
+var node = $.anchor(div);
Foo(node, {});
Fourthly, in cases like if/each/etc blocks, we can apply the textContent
optimisation. But we need to do it carefully — it can only be used when there are no out
transitions (excluding local transitions inside child blocks). After clearing the content, the anchor needs to be put back.
This optimisation part, even though it's the main reason for doing this, can be done separately — it probably makes sense to just focus on the hydration stuff first.
I'm not sure 'controlled' is the ideal name for this — it implies something different to me. I'm not sure what the best name would be to describe 'thing that is the only child of an element' — oneling is a word that means 'only child' though it's in somewhat rare usage; 'solo block' or 'standalone block' could work.
Importance
nice to have