From 6a51c9ef9b2bba65e534f18982ac093c73ff249e Mon Sep 17 00:00:00 2001 From: natxocc Date: Fri, 3 Apr 2026 21:22:25 +0200 Subject: [PATCH] Optimized for --- dist/sigpro.js | 42 +++++++++++++++++++++++------------------- dist/sigpro.min.js | 2 +- sigpro/index.js | 44 ++++++++++++++++++++++++-------------------- 3 files changed, 48 insertions(+), 40 deletions(-) diff --git a/dist/sigpro.js b/dist/sigpro.js index 5ab2a29..0df1fa9 100644 --- a/dist/sigpro.js +++ b/dist/sigpro.js @@ -277,21 +277,23 @@ const append = (child) => { if (Array.isArray(child)) return child.forEach(append); - if (typeof child === "function") { + if (child instanceof Node) { + el.appendChild(child); + } else if (typeof child === "function") { const marker = document.createTextNode(""); el.appendChild(marker); let nodes = []; el._cleanups.add($watch(() => { - const result = child(), nextNodes = (Array.isArray(result) ? result : [result]).map((item) => item?._isRuntime ? item.container : item instanceof Node ? item : document.createTextNode(item ?? "")); - nodes.forEach((node) => { - sweep(node); - node.remove(); + const res = child(), next = (Array.isArray(res) ? res : [res]).map((i) => i?._isRuntime ? i.container : i instanceof Node ? i : document.createTextNode(i ?? "")); + nodes.forEach((n) => { + sweep(n); + n.remove(); }); - nextNodes.forEach((node) => marker.parentNode?.insertBefore(node, marker)); - nodes = nextNodes; + next.forEach((n) => marker.parentNode?.insertBefore(n, marker)); + nodes = next; })); } else - el.appendChild(child instanceof Node ? child : document.createTextNode(child ?? "")); + el.appendChild(document.createTextNode(child ?? "")); }; append(content); return el; @@ -317,38 +319,40 @@ }; $if.not = (condition, thenVal, otherwiseVal) => $if(() => !(typeof condition === "function" ? condition() : condition), thenVal, otherwiseVal); var $for = (source, render, keyFn) => { - const marker = document.createComment("sigpro-for"); + const marker = document.createComment("sigpro-for-end"); let cache = new Map; $watch(() => { const items = (typeof source === "function" ? source() : source) || []; - const newCache = new Map; const parent = marker.parentNode; if (!parent) return; - const newOrder = items.map((item, i) => { + const newCache = new Map; + const newOrder = []; + for (let i = 0;i < items.length; i++) { + const item = items[i]; const key = keyFn ? keyFn(item, i) : i; let cached = cache.get(key); if (!cached) { const view = _view(() => render(item, i)); - const node = view.container.firstChild || document.createTextNode(""); + const node = view.container.firstElementChild || view.container.firstChild; cached = { node, destroy: view.destroy }; } else { cache.delete(key); } newCache.set(key, cached); - return cached; - }); + newOrder.push(cached.node); + } cache.forEach((c) => { c.destroy(); c.node.remove(); }); - let anchor = marker; + let currentAnchor = marker; for (let i = newOrder.length - 1;i >= 0; i--) { - const { node } = newOrder[i]; - if (node.nextSibling !== anchor) { - parent.insertBefore(node, anchor); + const node = newOrder[i]; + if (node.nextSibling !== currentAnchor) { + parent.insertBefore(node, currentAnchor); } - anchor = node; + currentAnchor = node; } cache = newCache; }); diff --git a/dist/sigpro.min.js b/dist/sigpro.min.js index 94335c4..e757e29 100644 --- a/dist/sigpro.min.js +++ b/dist/sigpro.min.js @@ -1 +1 @@ -(()=>{var{defineProperty:D,getOwnPropertyNames:w,getOwnPropertyDescriptor:k}=Object,y=Object.prototype.hasOwnProperty;var b=new WeakMap,g=(K)=>{var J=b.get(K),Z;if(J)return J;if(J=D({},"__esModule",{value:!0}),K&&typeof K==="object"||typeof K==="function")w(K).map((q)=>!y.call(J,q)&&D(J,q,{get:()=>K[q],enumerable:!(Z=k(K,q))||Z.enumerable}));return b.set(K,J),J};var v=(K,J)=>{for(var Z in J)D(K,Z,{get:J[Z],enumerable:!0,configurable:!0,set:(q)=>J[Z]=()=>q})};var d={};v(d,{$watch:()=>L,$router:()=>Q,$mount:()=>$,$if:()=>T,$html:()=>x,$for:()=>E,$:()=>_});var U=null,I=null,C=new Set,P=!1,M=new WeakMap,h=()=>{if(P)return;P=!0;while(C.size>0){let K=Array.from(C).sort((J,Z)=>(J.depth||0)-(Z.depth||0));C.clear();for(let J of K)if(!J._deleted)J()}P=!1},O=(K)=>{if(U&&!U._deleted)K.add(U),U._deps.add(K)},S=(K)=>{for(let J of K){if(J===U||J._deleted)continue;if(J._isComputed){if(J.markDirty(),J._subs)S(J._subs)}else C.add(J)}if(!P)queueMicrotask(h)},V=(K)=>{if(K._cleanups)K._cleanups.forEach((J)=>J()),K._cleanups.clear();K.childNodes?.forEach(V)},F=(K)=>{let J=new Set,Z=I,q=document.createElement("div");q.style.display="contents",I={cleanups:J};try{let W=K({onCleanup:(j)=>J.add(j)}),Y=(j)=>{if(!j)return;if(j._isRuntime)J.add(j.destroy),q.appendChild(j.container);else if(Array.isArray(j))j.forEach(Y);else q.appendChild(j instanceof Node?j:document.createTextNode(String(j)))};Y(W)}finally{I=Z}return{_isRuntime:!0,container:q,destroy:()=>{J.forEach((W)=>W()),V(q),q.remove()}}},_=(K,J=null)=>{if(typeof K==="function"){let W=new Set,Y,j=!0,X=()=>{if(X._deleted)return;X._deps.forEach((G)=>G.delete(X)),X._deps.clear();let B=U;U=X;try{let G=K();if(!Object.is(Y,G)||j)Y=G,j=!1,S(W)}finally{U=B}};if(X._deps=new Set,X._isComputed=!0,X._subs=W,X._deleted=!1,X.markDirty=()=>j=!0,X.stop=()=>{X._deleted=!0,X._deps.forEach((B)=>B.delete(X)),W.clear()},I)I.cleanups.add(X.stop);return()=>{if(j)X();return O(W),Y}}let Z=K;if(J)try{let W=localStorage.getItem(J);if(W!==null)Z=JSON.parse(W)}catch(W){console.warn("SigPro: LocalStorage locked",W)}let q=new Set;return(...W)=>{if(W.length){let Y=typeof W[0]==="function"?W[0](Z):W[0];if(!Object.is(Z,Y)){if(Z=Y,J)localStorage.setItem(J,JSON.stringify(Z));S(q)}}return O(q),Z}},L=(K,J)=>{let Z=Array.isArray(K),q=Z?J:K,W=Z?K:null;if(typeof q!=="function")return()=>{};let Y=I,j=()=>{if(j._deleted)return;j._deps.forEach((G)=>G.delete(j)),j._deps.clear(),j._cleanups.forEach((G)=>G()),j._cleanups.clear();let X=U,B=I;U=j,I={cleanups:j._cleanups},j.depth=X?X.depth+1:0;try{if(Z)U=null,q(),U=j,W.forEach((G)=>typeof G==="function"&&G());else q()}finally{U=X,I=B}};if(j._deps=new Set,j._cleanups=new Set,j._deleted=!1,j.stop=()=>{if(j._deleted)return;if(j._deleted=!0,C.delete(j),j._deps.forEach((X)=>X.delete(j)),j._cleanups.forEach((X)=>X()),Y)Y.cleanups.delete(j.stop)},Y)Y.cleanups.add(j.stop);return j(),j.stop},x=(K,J={},Z=[])=>{if(J instanceof Node||Array.isArray(J)||typeof J!=="object")Z=J,J={};let q=document.createElement(K),W=(j,X)=>(j==="src"||j==="href")&&String(X).toLowerCase().includes("javascript:")?"#":X;q._cleanups=new Set;for(let[j,X]of Object.entries(J)){if(j==="ref"){typeof X==="function"?X(q):X.current=q;continue}let B=typeof X==="function";if(["INPUT","TEXTAREA","SELECT"].includes(q.tagName)&&(j==="value"||j==="checked")&&B){q._cleanups.add(L(()=>{let A=X();if(q[j]!==A)q[j]=A}));let z=j==="checked"?"change":"input",H=(A)=>X(A.target[j]);q.addEventListener(z,H),q._cleanups.add(()=>q.removeEventListener(z,H))}else if(j.startsWith("on")){let z=j.slice(2).toLowerCase().split(".")[0],H=(A)=>X(A);q.addEventListener(z,H),q._cleanups.add(()=>q.removeEventListener(z,H))}else if(B)q._cleanups.add(L(()=>{let z=W(j,X());if(j==="class")q.className=z||"";else z==null?q.removeAttribute(j):q.setAttribute(j,z)}));else q.setAttribute(j,W(j,X))}let Y=(j)=>{if(Array.isArray(j))return j.forEach(Y);if(typeof j==="function"){let X=document.createTextNode("");q.appendChild(X);let B=[];q._cleanups.add(L(()=>{let G=j(),R=(Array.isArray(G)?G:[G]).map((z)=>z?._isRuntime?z.container:z instanceof Node?z:document.createTextNode(z??""));B.forEach((z)=>{V(z),z.remove()}),R.forEach((z)=>X.parentNode?.insertBefore(z,X)),B=R}))}else q.appendChild(j instanceof Node?j:document.createTextNode(j??""))};return Y(Z),q},T=(K,J,Z=null)=>{let q=document.createTextNode(""),W=x("div",{style:"display:contents"},[q]),Y=null,j=null;return L(()=>{let X=!!(typeof K==="function"?K():K);if(X!==j){if(j=X,Y)Y.destroy();let B=X?J:Z;if(B)Y=F(()=>typeof B==="function"?B():B),W.insertBefore(Y.container,q)}}),W};T.not=(K,J,Z)=>T(()=>!(typeof K==="function"?K():K),J,Z);var E=(K,J,Z)=>{let q=document.createComment("sigpro-for"),W=new Map;return L(()=>{let Y=(typeof K==="function"?K():K)||[],j=new Map,X=q.parentNode;if(!X)return;let B=Y.map((R,z)=>{let H=Z?Z(R,z):z,A=W.get(H);if(!A){let N=F(()=>J(R,z));A={node:N.container.firstChild||document.createTextNode(""),destroy:N.destroy}}else W.delete(H);return j.set(H,A),A});W.forEach((R)=>{R.destroy(),R.node.remove()});let G=q;for(let R=B.length-1;R>=0;R--){let{node:z}=B[R];if(z.nextSibling!==G)X.insertBefore(z,G);G=z}W=j}),q},Q=(K)=>{let J=_(window.location.hash.replace(/^#/,"")||"/");window.addEventListener("hashchange",()=>J(window.location.hash.replace(/^#/,"")||"/"));let Z=x("div",{class:"router-outlet"}),q=null;return L([J],async()=>{let W=J(),Y=K.find((j)=>{let X=j.path.split("/").filter(Boolean),B=W.split("/").filter(Boolean);return X.length===B.length&&X.every((G,R)=>G.startsWith(":")||G===B[R])})||K.find((j)=>j.path==="*");if(Y){let j=Y.component;if(typeof j==="function"&&j.toString().includes("import"))j=(await j()).default||await j();let X={};if(Y.path.split("/").filter(Boolean).forEach((B,G)=>{if(B.startsWith(":"))X[B.slice(1)]=W.split("/").filter(Boolean)[G]}),q)q.destroy();if(Q.params)Q.params(X);q=F(()=>{try{return typeof j==="function"?j(X):j}catch(B){return x("div",{class:"p-4 text-error"},"Error loading view")}}),Z.appendChild(q.container)}}),Z};Q.params=_({});Q.to=(K)=>window.location.hash=K.replace(/^#?\/?/,"#/");Q.back=()=>window.history.back();Q.path=()=>window.location.hash.replace(/^#/,"")||"/";var $=(K,J)=>{let Z=typeof J==="string"?document.querySelector(J):J;if(!Z)return;if(M.has(Z))M.get(Z).destroy();let q=F(typeof K==="function"?K:()=>K);return Z.replaceChildren(q.container),M.set(Z,q),q},m={$:_,$watch:L,$html:x,$if:T,$for:E,$router:Q,$mount:$};if(typeof window<"u")((J)=>{Object.keys(J).forEach((q)=>{window[q]=J[q]}),"div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer address ul ol li dl dt dd a em strong small i b u mark time sub sup pre code blockquote details summary dialog form label input textarea select button option fieldset legend table thead tbody tfoot tr th td caption img video audio canvas svg iframe picture source progress meter".split(/\s+/).forEach((q)=>{let W=q.charAt(0).toUpperCase()+q.slice(1);if(!(W in window))window[W]=(Y,j)=>x(q,Y,j)}),window.SigPro=Object.freeze(J)})(m);})(); +(()=>{var{defineProperty:M,getOwnPropertyNames:w,getOwnPropertyDescriptor:k}=Object,y=Object.prototype.hasOwnProperty;var b=new WeakMap,g=(K)=>{var J=b.get(K),Z;if(J)return J;if(J=M({},"__esModule",{value:!0}),K&&typeof K==="object"||typeof K==="function")w(K).map((q)=>!y.call(J,q)&&M(J,q,{get:()=>K[q],enumerable:!(Z=k(K,q))||Z.enumerable}));return b.set(K,J),J};var v=(K,J)=>{for(var Z in J)M(K,Z,{get:J[Z],enumerable:!0,configurable:!0,set:(q)=>J[Z]=()=>q})};var d={};v(d,{$watch:()=>Q,$router:()=>x,$mount:()=>$,$if:()=>T,$html:()=>C,$for:()=>E,$:()=>_});var U=null,L=null,P=new Set,A=!1,S=new WeakMap,m=()=>{if(A)return;A=!0;while(P.size>0){let K=Array.from(P).sort((J,Z)=>(J.depth||0)-(Z.depth||0));P.clear();for(let J of K)if(!J._deleted)J()}A=!1},O=(K)=>{if(U&&!U._deleted)K.add(U),U._deps.add(K)},V=(K)=>{for(let J of K){if(J===U||J._deleted)continue;if(J._isComputed){if(J.markDirty(),J._subs)V(J._subs)}else P.add(J)}if(!A)queueMicrotask(m)},N=(K)=>{if(K._cleanups)K._cleanups.forEach((J)=>J()),K._cleanups.clear();K.childNodes?.forEach(N)},F=(K)=>{let J=new Set,Z=L,q=document.createElement("div");q.style.display="contents",L={cleanups:J};try{let W=K({onCleanup:(j)=>J.add(j)}),Y=(j)=>{if(!j)return;if(j._isRuntime)J.add(j.destroy),q.appendChild(j.container);else if(Array.isArray(j))j.forEach(Y);else q.appendChild(j instanceof Node?j:document.createTextNode(String(j)))};Y(W)}finally{L=Z}return{_isRuntime:!0,container:q,destroy:()=>{J.forEach((W)=>W()),N(q),q.remove()}}},_=(K,J=null)=>{if(typeof K==="function"){let W=new Set,Y,j=!0,X=()=>{if(X._deleted)return;X._deps.forEach((G)=>G.delete(X)),X._deps.clear();let z=U;U=X;try{let G=K();if(!Object.is(Y,G)||j)Y=G,j=!1,V(W)}finally{U=z}};if(X._deps=new Set,X._isComputed=!0,X._subs=W,X._deleted=!1,X.markDirty=()=>j=!0,X.stop=()=>{X._deleted=!0,X._deps.forEach((z)=>z.delete(X)),W.clear()},L)L.cleanups.add(X.stop);return()=>{if(j)X();return O(W),Y}}let Z=K;if(J)try{let W=localStorage.getItem(J);if(W!==null)Z=JSON.parse(W)}catch(W){console.warn("SigPro: LocalStorage locked",W)}let q=new Set;return(...W)=>{if(W.length){let Y=typeof W[0]==="function"?W[0](Z):W[0];if(!Object.is(Z,Y)){if(Z=Y,J)localStorage.setItem(J,JSON.stringify(Z));V(q)}}return O(q),Z}},Q=(K,J)=>{let Z=Array.isArray(K),q=Z?J:K,W=Z?K:null;if(typeof q!=="function")return()=>{};let Y=L,j=()=>{if(j._deleted)return;j._deps.forEach((G)=>G.delete(j)),j._deps.clear(),j._cleanups.forEach((G)=>G()),j._cleanups.clear();let X=U,z=L;U=j,L={cleanups:j._cleanups},j.depth=X?X.depth+1:0;try{if(Z)U=null,q(),U=j,W.forEach((G)=>typeof G==="function"&&G());else q()}finally{U=X,L=z}};if(j._deps=new Set,j._cleanups=new Set,j._deleted=!1,j.stop=()=>{if(j._deleted)return;if(j._deleted=!0,P.delete(j),j._deps.forEach((X)=>X.delete(j)),j._cleanups.forEach((X)=>X()),Y)Y.cleanups.delete(j.stop)},Y)Y.cleanups.add(j.stop);return j(),j.stop},C=(K,J={},Z=[])=>{if(J instanceof Node||Array.isArray(J)||typeof J!=="object")Z=J,J={};let q=document.createElement(K),W=(j,X)=>(j==="src"||j==="href")&&String(X).toLowerCase().includes("javascript:")?"#":X;q._cleanups=new Set;for(let[j,X]of Object.entries(J)){if(j==="ref"){typeof X==="function"?X(q):X.current=q;continue}let z=typeof X==="function";if(["INPUT","TEXTAREA","SELECT"].includes(q.tagName)&&(j==="value"||j==="checked")&&z){q._cleanups.add(Q(()=>{let H=X();if(q[j]!==H)q[j]=H}));let B=j==="checked"?"change":"input",I=(H)=>X(H.target[j]);q.addEventListener(B,I),q._cleanups.add(()=>q.removeEventListener(B,I))}else if(j.startsWith("on")){let B=j.slice(2).toLowerCase().split(".")[0],I=(H)=>X(H);q.addEventListener(B,I),q._cleanups.add(()=>q.removeEventListener(B,I))}else if(z)q._cleanups.add(Q(()=>{let B=W(j,X());if(j==="class")q.className=B||"";else B==null?q.removeAttribute(j):q.setAttribute(j,B)}));else q.setAttribute(j,W(j,X))}let Y=(j)=>{if(Array.isArray(j))return j.forEach(Y);if(j instanceof Node)q.appendChild(j);else if(typeof j==="function"){let X=document.createTextNode("");q.appendChild(X);let z=[];q._cleanups.add(Q(()=>{let G=j(),R=(Array.isArray(G)?G:[G]).map((B)=>B?._isRuntime?B.container:B instanceof Node?B:document.createTextNode(B??""));z.forEach((B)=>{N(B),B.remove()}),R.forEach((B)=>X.parentNode?.insertBefore(B,X)),z=R}))}else q.appendChild(document.createTextNode(j??""))};return Y(Z),q},T=(K,J,Z=null)=>{let q=document.createTextNode(""),W=C("div",{style:"display:contents"},[q]),Y=null,j=null;return Q(()=>{let X=!!(typeof K==="function"?K():K);if(X!==j){if(j=X,Y)Y.destroy();let z=X?J:Z;if(z)Y=F(()=>typeof z==="function"?z():z),W.insertBefore(Y.container,q)}}),W};T.not=(K,J,Z)=>T(()=>!(typeof K==="function"?K():K),J,Z);var E=(K,J,Z)=>{let q=document.createComment("sigpro-for-end"),W=new Map;return Q(()=>{let Y=(typeof K==="function"?K():K)||[],j=q.parentNode;if(!j)return;let X=new Map,z=[];for(let R=0;RJ(B,R));H={node:D.container.firstElementChild||D.container.firstChild,destroy:D.destroy}}else W.delete(I);X.set(I,H),z.push(H.node)}W.forEach((R)=>{R.destroy(),R.node.remove()});let G=q;for(let R=z.length-1;R>=0;R--){let B=z[R];if(B.nextSibling!==G)j.insertBefore(B,G);G=B}W=X}),q},x=(K)=>{let J=_(window.location.hash.replace(/^#/,"")||"/");window.addEventListener("hashchange",()=>J(window.location.hash.replace(/^#/,"")||"/"));let Z=C("div",{class:"router-outlet"}),q=null;return Q([J],async()=>{let W=J(),Y=K.find((j)=>{let X=j.path.split("/").filter(Boolean),z=W.split("/").filter(Boolean);return X.length===z.length&&X.every((G,R)=>G.startsWith(":")||G===z[R])})||K.find((j)=>j.path==="*");if(Y){let j=Y.component;if(typeof j==="function"&&j.toString().includes("import"))j=(await j()).default||await j();let X={};if(Y.path.split("/").filter(Boolean).forEach((z,G)=>{if(z.startsWith(":"))X[z.slice(1)]=W.split("/").filter(Boolean)[G]}),q)q.destroy();if(x.params)x.params(X);q=F(()=>{try{return typeof j==="function"?j(X):j}catch(z){return C("div",{class:"p-4 text-error"},"Error loading view")}}),Z.appendChild(q.container)}}),Z};x.params=_({});x.to=(K)=>window.location.hash=K.replace(/^#?\/?/,"#/");x.back=()=>window.history.back();x.path=()=>window.location.hash.replace(/^#/,"")||"/";var $=(K,J)=>{let Z=typeof J==="string"?document.querySelector(J):J;if(!Z)return;if(S.has(Z))S.get(Z).destroy();let q=F(typeof K==="function"?K:()=>K);return Z.replaceChildren(q.container),S.set(Z,q),q},h={$:_,$watch:Q,$html:C,$if:T,$for:E,$router:x,$mount:$};if(typeof window<"u")((J)=>{Object.keys(J).forEach((q)=>{window[q]=J[q]}),"div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer address ul ol li dl dt dd a em strong small i b u mark time sub sup pre code blockquote details summary dialog form label input textarea select button option fieldset legend table thead tbody tfoot tr th td caption img video audio canvas svg iframe picture source progress meter".split(/\s+/).forEach((q)=>{let W=q.charAt(0).toUpperCase()+q.slice(1);if(!(W in window))window[W]=(Y,j)=>C(q,Y,j)}),window.SigPro=Object.freeze(J)})(h);})(); diff --git a/sigpro/index.js b/sigpro/index.js index a21c2c3..5981e1f 100644 --- a/sigpro/index.js +++ b/sigpro/index.js @@ -252,19 +252,21 @@ const $html = (tag, props = {}, content = []) => { const append = (child) => { if (Array.isArray(child)) return child.forEach(append); - if (typeof child === "function") { + if (child instanceof Node) { + el.appendChild(child); + } else if (typeof child === "function") { const marker = document.createTextNode(""); el.appendChild(marker); let nodes = []; el._cleanups.add($watch(() => { - const result = child(), nextNodes = (Array.isArray(result) ? result : [result]).map((item) => - item?._isRuntime ? item.container : item instanceof Node ? item : document.createTextNode(item ?? "") + const res = child(), next = (Array.isArray(res) ? res : [res]).map((i) => + i?._isRuntime ? i.container : i instanceof Node ? i : document.createTextNode(i ?? "") ); - nodes.forEach((node) => { sweep(node); node.remove(); }); - nextNodes.forEach((node) => marker.parentNode?.insertBefore(node, marker)); - nodes = nextNodes; + nodes.forEach((n) => { sweep(n); n.remove(); }); + next.forEach((n) => marker.parentNode?.insertBefore(n, marker)); + nodes = next; })); - } else el.appendChild(child instanceof Node ? child : document.createTextNode(child ?? "")); + } else el.appendChild(document.createTextNode(child ?? "")); }; append(content); return el; @@ -307,43 +309,45 @@ $if.not = (condition, thenVal, otherwiseVal) => $if(() => !(typeof condition === * @returns {HTMLElement} A reactive container (display: contents). */ const $for = (source, render, keyFn) => { - const marker = document.createComment("sigpro-for"); + const marker = document.createComment("sigpro-for-end"); let cache = new Map(); - + $watch(() => { const items = (typeof source === "function" ? source() : source) || []; - const newCache = new Map(); const parent = marker.parentNode; - if (!parent) return; - const newOrder = items.map((item, i) => { + const newCache = new Map(); + const newOrder = []; + + for (let i = 0; i < items.length; i++) { + const item = items[i]; const key = keyFn ? keyFn(item, i) : i; let cached = cache.get(key); if (!cached) { const view = _view(() => render(item, i)); - const node = view.container.firstChild || document.createTextNode(""); + const node = view.container.firstElementChild || view.container.firstChild; cached = { node, destroy: view.destroy }; } else { cache.delete(key); } newCache.set(key, cached); - return cached; - }); + newOrder.push(cached.node); + } cache.forEach(c => { c.destroy(); c.node.remove(); }); - let anchor = marker; + let currentAnchor = marker; for (let i = newOrder.length - 1; i >= 0; i--) { - const { node } = newOrder[i]; - if (node.nextSibling !== anchor) { - parent.insertBefore(node, anchor); + const node = newOrder[i]; + if (node.nextSibling !== currentAnchor) { + parent.insertBefore(node, currentAnchor); } - anchor = node; + currentAnchor = node; } cache = newCache;