Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions .changeset/counted-branch-ends.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@marko/runtime-tags": patch
---

Loop and conditional branches whose top-level content is statically countable no longer write start comments in server rendered HTML; the end marker carries the node count instead.
8 changes: 8 additions & 0 deletions .changeset/lucky-rules-attack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@marko/runtime-tags": patch
---

Stop materializing boundary nodes around `if`/`for`/dynamic tag content: client
rendered templates no longer pad the ends of a template or branch body, and
resuming a server rendered branch now adopts its real edge nodes instead of
keeping the start comment and inserting a text node.
12 changes: 6 additions & 6 deletions .sizes.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
{
"name": "*",
"total": {
"min": 26671,
"brotli": 9915
"min": 27235,
"brotli": 10132
}
},
{
Expand Down Expand Up @@ -48,12 +48,12 @@
"brotli": 364
},
"runtime": {
"min": 6558,
"brotli": 2884
"min": 6749,
"brotli": 2953
},
"total": {
"min": 7203,
"brotli": 3248
"min": 7394,
"brotli": 3317
}
},
{
Expand Down
124 changes: 73 additions & 51 deletions .sizes/comments.csr/runtime.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// size: 6558 (min) 2884 (brotli)
// size: 6749 (min) 2953 (brotli)
//#region packages/runtime-tags/dist/dom.mjs
let decodeAccessor = (num) => (num + (num < 26 ? 10 : num < 962 ? 334 : 11998)).toString(36),
delegate = (type, handler) =>
Expand Down Expand Up @@ -126,6 +126,13 @@ function unsubscribe(subscribers) {
function removeAndDestroyBranch(branch) {
(destroyBranch(branch), removeChildNodes(branch.S, branch.K));
}
function fixBranchEdges(branch, oldStart, oldEnd, newStart, newEnd) {
for (; branch; branch = branch.N) {
if (branch.S === oldStart) branch.S = newStart;
else if (branch.K !== oldEnd) return;
branch.K === oldEnd && (branch.K = newEnd);
}
}
function insertBranchBefore(branch, parentNode, nextSibling) {
insertChildNodes(parentNode, nextSibling, branch.S, branch.K);
}
Expand Down Expand Up @@ -338,16 +345,23 @@ function setConditionalRenderer(scope, nodeAccessor, newRenderer, createBranch)
referenceNode.nodeType > 1 ? (prevBranch?.S || referenceNode).parentNode : referenceNode,
newBranch = (scope["A" + nodeAccessor] =
newRenderer && createBranch(scope.$, newRenderer, scope, parentNode));
referenceNode === parentNode
? (prevBranch && (destroyBranch(prevBranch), (referenceNode.textContent = "")),
newBranch && insertBranchBefore(newBranch, parentNode, null))
: prevBranch
? (newBranch
? insertBranchBefore(newBranch, parentNode, prevBranch.S)
: parentNode.insertBefore(referenceNode, prevBranch.S),
removeAndDestroyBranch(prevBranch))
: newBranch &&
(insertBranchBefore(newBranch, parentNode, referenceNode), referenceNode.remove());
if (referenceNode === parentNode)
(prevBranch && (destroyBranch(prevBranch), (referenceNode.textContent = "")),
newBranch && insertBranchBefore(newBranch, parentNode, null));
else if (prevBranch || newBranch) {
let oldStart = prevBranch ? prevBranch.S : referenceNode;
(newBranch
? insertBranchBefore(newBranch, parentNode, oldStart)
: parentNode.insertBefore(referenceNode, oldStart),
fixBranchEdges(
scope.F,
oldStart,
prevBranch ? prevBranch.K : referenceNode,
newBranch ? newBranch.S : referenceNode,
newBranch ? newBranch.K : referenceNode,
),
prevBranch ? removeAndDestroyBranch(prevBranch) : referenceNode.remove());
}
}
/* @__NO_SIDE_EFFECTS__ */
function loop(forEach) {
Expand Down Expand Up @@ -401,52 +415,60 @@ function loop(forEach) {
? ((afterReference = oldScopes[oldEnd].K.nextSibling),
newLen || parentNode.insertBefore(referenceNode, afterReference))
: newLen && ((afterReference = referenceNode.nextSibling), referenceNode.remove())),
!hasPotentialMoves)
hasPotentialMoves)
) {
if (oldScopesByKey) oldScopesByKey.forEach(removeAndDestroyBranch);
else for (let i = newLen; i < oldLen; i++) removeAndDestroyBranch(oldScopes[i]);
for (; oldEnd >= start && newEnd >= start && oldScopes[oldEnd] === newScopes[newEnd];)
(oldEnd--, newEnd--);
if (
(oldEnd + 1 < oldLen && (afterReference = oldScopes[oldEnd + 1].S),
start > oldEnd || start > newEnd)
)
for (let i = start; i <= newEnd; i++)
insertBranchBefore(newScopes[i], parentNode, afterReference);
else {
let diffLen = newEnd - start + 1,
sources = Array(diffLen),
pred = Array(diffLen),
tails = [],
tail = -1,
lo,
hi,
mid;
for (let i = diffLen; i--;) sources[i] = newScopes[start + i].I ?? -1;
for (let i = 0; i < diffLen; i++)
if (~sources[i])
if (tail < 0 || sources[tails[tail]] < sources[i])
(~tail && (pred[i] = tails[tail]), (tails[++tail] = i));
else {
for (lo = 0, hi = tail; lo < hi;)
((mid = ((lo + hi) / 2) | 0),
sources[tails[mid]] < sources[i] ? (lo = mid + 1) : (hi = mid));
sources[i] < sources[tails[lo]] &&
(lo > 0 && (pred[i] = tails[lo - 1]), (tails[lo] = i));
}
for (hi = tails[tail], lo = tail + 1; lo-- > 0;) ((tails[lo] = hi), (hi = pred[hi]));
for (let i = diffLen; i--;)
(~tail && i === tails[tail]
? tail--
: insertBranchBefore(newScopes[start + i], parentNode, afterReference),
(afterReference = newScopes[start + i].S));
}
} else {
oldLen &&
(oldScopes.forEach(hasSiblings ? removeAndDestroyBranch : destroyBranch),
hasSiblings || (parentNode.textContent = ""));
for (let newScope of newScopes) insertBranchBefore(newScope, parentNode, afterReference);
return;
}
if (oldScopesByKey) oldScopesByKey.forEach(removeAndDestroyBranch);
else for (let i = newLen; i < oldLen; i++) removeAndDestroyBranch(oldScopes[i]);
for (; oldEnd >= start && newEnd >= start && oldScopes[oldEnd] === newScopes[newEnd];)
(oldEnd--, newEnd--);
if (
(oldEnd + 1 < oldLen && (afterReference = oldScopes[oldEnd + 1].S),
start > oldEnd || start > newEnd)
) {
for (let i = start; i <= newEnd; i++)
insertBranchBefore(newScopes[i], parentNode, afterReference);
return;
}
let diffLen = newEnd - start + 1,
sources = Array(diffLen),
pred = Array(diffLen),
tails = [],
tail = -1,
lo,
hi,
mid;
for (let i = diffLen; i--;) sources[i] = newScopes[start + i].I ?? -1;
for (let i = 0; i < diffLen; i++)
if (~sources[i])
if (tail < 0 || sources[tails[tail]] < sources[i])
(~tail && (pred[i] = tails[tail]), (tails[++tail] = i));
else {
for (lo = 0, hi = tail; lo < hi;)
((mid = ((lo + hi) / 2) | 0),
sources[tails[mid]] < sources[i] ? (lo = mid + 1) : (hi = mid));
sources[i] < sources[tails[lo]] &&
(lo > 0 && (pred[i] = tails[lo - 1]), (tails[lo] = i));
}
for (hi = tails[tail], lo = tail + 1; lo-- > 0;) ((tails[lo] = hi), (hi = pred[hi]));
for (let i = diffLen; i--;)
(~tail && i === tails[tail]
? tail--
: insertBranchBefore(newScopes[start + i], parentNode, afterReference),
(afterReference = newScopes[start + i].S));
hasSiblings &&
fixBranchEdges(
scope.F,
oldLen ? oldScopes[0].S : referenceNode,
oldLen ? oldScopes[oldLen - 1].K : referenceNode,
newLen ? newScopes[0].S : referenceNode,
newLen ? newScopes[newLen - 1].K : referenceNode,
);
}
);
};
Expand Down
Loading
Loading