Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@ryansolid
Last active October 22, 2022 13:27
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryansolid/71e2b160df4db33fcca2862355377983 to your computer and use it in GitHub Desktop.
Save ryansolid/71e2b160df4db33fcca2862355377983 to your computer and use it in GitHub Desktop.
Size Comparison Vue vs Svelte vs Solid

Based on Evan You's methodology: https://github.com/yyx990803/vue-svelte-size-analysis

Table

Vue Vue (SSR) Svelte Svelte (SSR) Solid Solid (SSR)
Source 3.93kb - 3.31kb - 4.98kb -
Compiled w/o imports (min) 2.73kb - 5.01kb (183.52%) 6.59kb (241.39%) 3.68kb (134.805) 3.96kb (145.05%)
Compiled w/o imports (min+gz) 1.25kb - 2.13kb (170.40%) 2.68kb (214.40%) 1.46kb (116.80%) 1.57kb (125.60%)
Compiled w/o imports (min+brotli) 1.10kb - 1.88kb (170.91%) 2.33kb (211.82%) 1.26kb (114.55%) 1.32kb (120.00%)
Vite component chunk (min+brotli) 1.13kb - 1.95kb (172.26%) 2.41kb (213.27%) 1.30kb (115.04%) 1.37kb (121.24%)
Vite vendor chunk (min+brotli) 16.89kb 17.78kb 1.85kb 2.13kb 3.86kb 3.89kb

Client

vendor(Vue) - 13.03kb difference

vendor(Svelte) - 2.01kb difference

component(Vue) - .16kb difference

component(Svelte) - .62kb difference

Solid is larger than Vue at 81.4 TodoMVC app components

Svelte is larger than Solid at 3.2 TodoMVC app components

SSR

vendor(Vue) - 13.89kb difference

vendor(Svelte) - 1.66kb difference

component(Vue) - .22kb difference

component(Svelte) - 1.01kb difference

Solid is larger than Vue at 63.1 TodoMVC app components

Svelte is larger than Solid at 1.6 TodoMVC app components

Analysis

Evan handles the analysis well in his repo: https://github.com/yyx990803/vue-svelte-size-analysis.

Between these 3 options Solid is the smaller between ~3 TodoMVC apps and ~80 TodoMVC apps on the page which probably covers most common cases. SSR does narrow the band a bit as Solid's compiled output for hydration is a little larger. I suspect Preact would likely take piece of this range as well if included.

Keep in mind these are full TodoMVC apps as components. So they are on the larger size. If you were to look at an idiomatic React implementation each of these would be 3-4 components. So at I think one should 3x those numbers if you want to think in components.

So from that perspective apps with like 9-12 or so components probably benefit still from using Svelte. Things like mostly static sites, with a few islands of interactivity. Your Hackernews sites etc.. Vue starts looking attractive in the ~250 component range.

Truthfully this matters most on initial page load. So let's reverse it. If you value the wisdom of the Chrome Team in The Cost of JavaScript. We probably should be aiming that initial payload to be no larger than 70kb of this code, considering additional cost of 3rd party libraries like routing, and data fetching.

How many TodoMVC app components does that get you in each Framework on your page target byte size.

Vue Svelte Solid
10kb - 4.3 4.7
20kb 2.8 9.7 12.4
40kb 21 20.3 28.7
70kb 48.3 36.3 52.5

Closing Thoughts

I've never tried optimizing for size on a per component basis for Solid so I'm sure I'm leaving some stuff on the table. I do some things to create monomorphic objects for performance that add a ~100 bytes compressed or so for an app this size. I'm also using Stores here which add about 1kb to the runtime since that is what the official TodoMVC uses. We can revisit that if it makes sense.

But what should be clear though is that our perspective of what is good is largely affected by what our expectations are in terms of size. Some will see this and be Vue is better choice for enterprise apps, but I think that's the wrong take away. Need to look at what ranges make sense for the type of experience you are offering and set targets from there. What you should be seeing is that in the 50-80kb range (where large apps should be aiming for initial load) all these solutions are relatively comparable. For smaller needs smaller runtimes still make a considerable difference, for your blog sites and content sites. But it's worth noting for load/parse/execution time is 10kb very different than 20kb. Probably not for most of your visitors. So will all things take it with good measure as guide but nothing more.

const v=e('<section class="main"><input id="toggle-all" class="toggle-all" type="checkbox"><label for="toggle-all"></label><ul class="todo-list"></ul></section>',7),$=e('<button class="clear-completed">Clear completed</button>',2),f=e('<footer class="footer"><span class="todo-count"><strong></strong> <!#><!/> left</span><ul class="filters"><li><a href="#/">All</a></li><li><a href="#/active">Active</a></li><li><a href="#/completed">Completed</a></li></ul><!#><!/></footer>',24),m=e('<section class="todoapp"><header class="header"><h1>todos</h1><input class="new-todo" placeholder="What needs to be done?"></header><!#><!/></section>',9),b=e('<input class="edit">',1),S=e('<li class="todo"><div class="view"><input class="toggle" type="checkbox"><label></label><button class="destroy"></button></div><!#><!/></li>',11);t((()=>{const[e,t]=function(e){const t=localStorage.getItem("todos-solid"),[o,i]=p(t?JSON.parse(t):e);return u((()=>localStorage.setItem("todos-solid",JSON.stringify(o)))),[o,i]}({counter:1,todos:[],showMode:"all",editingTodoId:null}),o=g((()=>e.todos.length-e.todos.filter((e=>e.completed)).length)),k=e=>t("todos",(t=>t.filter((t=>t.id!==e)))),x=e=>t("todos",(t=>t.id===e.id),e),w=()=>t("todos",(e=>e.filter((e=>!e.completed)))),y=e=>t("editingTodoId",e),_=({target:o,keyCode:i})=>{const l=o.value.trim();13===i&&l&&(t({todos:[{title:l,id:e.counter,completed:!1},...e.todos],counter:e.counter+1}),o.value="")},C=(t,{target:{value:o}})=>{const i=o.trim();e.editingTodoId===t&&i&&(x({id:t,title:i}),y())},I=(e,{target:{checked:t}})=>x({id:e,completed:t}),L=(e,t)=>{13===t.keyCode?C(e,t):27===t.keyCode&&y()},M=()=>t("showMode",location.hash.slice(2)||"all");return window.addEventListener("hashchange",M),h((()=>window.removeEventListener("hashchange",M))),(()=>{const g=i(m),h=g.firstChild,u=h.firstChild.nextSibling,p=h.nextSibling,[x,M]=l(p.nextSibling);return u.$$keydown=_,d(g,s(n,{get when(){return e.todos.length>0},get children(){return[(()=>{const g=i(v),h=g.firstChild,u=h.nextSibling.nextSibling;return h.$$input=({target:{checked:e}})=>{return t("todos",(e=>e.completed!==o),{completed:o=e});var o},d(u,s(c,{get each(){return t=e.todos,"active"===e.showMode?t.filter((e=>!e.completed)):"completed"===e.showMode?t.filter((e=>e.completed)):t;var t},children:t=>(()=>{const o=i(S),c=o.firstChild,g=c.firstChild,h=g.nextSibling,u=h.nextSibling,p=c.nextSibling,[v,$]=l(p.nextSibling);return g.$$input=I,g.$$inputData=t.id,h.$$dblclick=y,h.$$dblclickData=t.id,d(h,(()=>t.title),void 0,Array.prototype.slice.call(h.childNodes,0)),u.$$click=k,u.$$clickData=t.id,d(o,s(n,{get when(){return e.editingTodoId===t.id},get children(){const e=i(b);var o;return o=e,setTimeout((()=>o.focus())),e.$$keyup=L,e.$$keyupData=t.id,e.$$focusout=C,e.$$focusoutData=t.id,r((()=>e.value=t.title)),a(),e}}),v,$),r((i=>{const l=e.editingTodoId===t.id,d=t.completed,s=t.completed;return l!==i._v$4&&o.classList.toggle("editing",i._v$4=l),d!==i._v$5&&o.classList.toggle("completed",i._v$5=d),s!==i._v$6&&(g.checked=i._v$6=s),i}),{_v$4:void 0,_v$5:void 0,_v$6:void 0}),a(),o})()}),void 0,Array.prototype.slice.call(u.childNodes,0)),r((()=>h.checked=!o())),a(),g})(),(()=>{const t=i(f),c=t.firstChild,g=c.firstChild,h=g.nextSibling.nextSibling,[u,p]=l(h.nextSibling);u.nextSibling;const v=c.nextSibling,m=v.firstChild,b=m.firstChild,S=m.nextSibling,k=S.firstChild,x=S.nextSibling.firstChild,y=v.nextSibling,[_,C]=l(y.nextSibling);return d(g,o,void 0,Array.prototype.slice.call(g.childNodes,0)),d(c,(()=>1===o()?" item ":" items "),u,p),d(t,s(n,{get when(){return o()!==e.todos.length},get children(){const e=i($);return e.$$click=w,a(),e}}),_,C),r((t=>{const o="all"===e.showMode,i="active"===e.showMode,l="completed"===e.showMode;return o!==t._v$&&b.classList.toggle("selected",t._v$=o),i!==t._v$2&&k.classList.toggle("selected",t._v$2=i),l!==t._v$3&&x.classList.toggle("selected",t._v$3=l),t}),{_v$:void 0,_v$2:void 0,_v$3:void 0}),t})()]}}),x,M),a(),g})()}),document.getElementById("app")),o(["keydown","input","click","dblclick","focusout","keyup"]);
const u=e('<section class="main"><input id="toggle-all" class="toggle-all" type="checkbox"><label for="toggle-all"></label><ul class="todo-list"></ul></section>',7),h=e('<button class="clear-completed">Clear completed</button>',2),$=e('<footer class="footer"><span class="todo-count"><strong></strong> <!> left</span><ul class="filters"><li><a href="#/">All</a></li><li><a href="#/active">Active</a></li><li><a href="#/completed">Completed</a></li></ul></footer>',21),p=e('<section class="todoapp"><header class="header"><h1>todos</h1><input class="new-todo" placeholder="What needs to be done?"></header></section>',7),v=e('<input class="edit">',1),f=e('<li class="todo"><div class="view"><input class="toggle" type="checkbox"><label></label><button class="destroy"></button></div></li>',9);t((()=>{const[e,t]=function(e){const t=localStorage.getItem("todos-solid"),[o,l]=g(t?JSON.parse(t):e);return a((()=>localStorage.setItem("todos-solid",JSON.stringify(o)))),[o,l]}({counter:1,todos:[],showMode:"all",editingTodoId:null}),o=c((()=>e.todos.length-e.todos.filter((e=>e.completed)).length)),m=e=>t("todos",(t=>t.filter((t=>t.id!==e)))),b=e=>t("todos",(t=>t.id===e.id),e),k=()=>t("todos",(e=>e.filter((e=>!e.completed)))),w=e=>t("editingTodoId",e),_=({target:o,keyCode:l})=>{const i=o.value.trim();13===l&&i&&(t({todos:[{title:i,id:e.counter,completed:!1},...e.todos],counter:e.counter+1}),o.value="")},C=(t,{target:{value:o}})=>{const l=o.trim();e.editingTodoId===t&&l&&(b({id:t,title:l}),w())},S=(e,{target:{checked:t}})=>b({id:e,completed:t}),x=(e,t)=>{13===t.keyCode?C(e,t):27===t.keyCode&&w()},y=()=>t("showMode",location.hash.slice(2)||"all");return window.addEventListener("hashchange",y),r((()=>window.removeEventListener("hashchange",y))),(()=>{const c=p.cloneNode(!0);return c.firstChild.firstChild.nextSibling.$$keydown=_,l(c,i(d,{get when(){return e.todos.length>0},get children(){return[(()=>{const c=u.cloneNode(!0),r=c.firstChild,a=r.nextSibling.nextSibling;return r.$$input=({target:{checked:e}})=>{return t("todos",(e=>e.completed!==o),{completed:o=e});var o},l(a,i(s,{get each(){return t=e.todos,"active"===e.showMode?t.filter((e=>!e.completed)):"completed"===e.showMode?t.filter((e=>e.completed)):t;var t},children:t=>(()=>{const o=f.cloneNode(!0),s=o.firstChild.firstChild,c=s.nextSibling,r=c.nextSibling;return s.$$input=S,s.$$inputData=t.id,c.$$dblclick=w,c.$$dblclickData=t.id,l(c,(()=>t.title)),r.$$click=m,r.$$clickData=t.id,l(o,i(d,{get when(){return e.editingTodoId===t.id},get children(){const e=v.cloneNode(!0);var o;return o=e,setTimeout((()=>o.focus())),e.$$keyup=x,e.$$keyupData=t.id,e.$$focusout=C,e.$$focusoutData=t.id,n((()=>e.value=t.title)),e}}),null),n((l=>{const i=e.editingTodoId===t.id,d=t.completed,n=t.completed;return i!==l._v$4&&o.classList.toggle("editing",l._v$4=i),d!==l._v$5&&o.classList.toggle("completed",l._v$5=d),n!==l._v$6&&(s.checked=l._v$6=n),l}),{_v$4:void 0,_v$5:void 0,_v$6:void 0}),o})()})),n((()=>r.checked=!o())),c})(),(()=>{const t=$.cloneNode(!0),s=t.firstChild,c=s.firstChild,r=c.nextSibling.nextSibling;r.nextSibling;const a=s.nextSibling.firstChild,g=a.firstChild,u=a.nextSibling,p=u.firstChild,v=u.nextSibling.firstChild;return l(c,o),l(s,(()=>1===o()?" item ":" items "),r),l(t,i(d,{get when(){return o()!==e.todos.length},get children(){const e=h.cloneNode(!0);return e.$$click=k,e}}),null),n((t=>{const o="all"===e.showMode,l="active"===e.showMode,i="completed"===e.showMode;return o!==t._v$&&g.classList.toggle("selected",t._v$=o),l!==t._v$2&&p.classList.toggle("selected",t._v$2=l),i!==t._v$3&&v.classList.toggle("selected",t._v$3=i),t}),{_v$:void 0,_v$2:void 0,_v$3:void 0}),t})()]}}),null),c})()}),document.getElementById("app")),o(["keydown","input","click","dblclick","focusout","keyup"]);
const e=Symbol("solid-proxy"),t={equals:(e,t)=>e===t};let n=x;const r={},o={owned:null,cleanups:null,context:null,owner:null};var l=null;let s=null,i=null,u=null,c=null,f=0;function a(e,t){t&&(l=t);const n=s,r=l,i=0===e.length?o:{owned:null,cleanups:null,context:null,owner:r,attached:!!t};let u;l=i,s=null;try{j((()=>u=e((()=>k(i)))),!0)}finally{s=n,l=r}return u}function d(e,n){n=n?Object.assign({},t,n):t;const o={value:e,observers:null,observerSlots:null,pending:r,comparator:n.equals||void 0};return[w.bind(o),e=>("function"==typeof e&&(e=e(o.pending!==r?o.pending:o.value)),A(o,e))]}function h(e,t,n){m(S(e,t,!1))}function p(e,t,r){n=C;const o=S(e,t,!1);o.user=!0,c&&c.push(o)}function g(e,n,o){o=o?Object.assign({},t,o):t;const l=S(e,n,!0);return l.pending=r,l.observers=null,l.observerSlots=null,l.state=0,l.comparator=o.equals||void 0,m(l),w.bind(l)}function b(e){if(i)return e();let t;const n=i=[];try{t=e()}finally{i=null}return j((()=>{for(let e=0;e<n.length;e+=1){const t=n[e];if(t.pending!==r){const e=t.pending;t.pending=r,A(t,e)}}}),!1),t}function y(e){let t,n=s;return s=null,t=e(),s=n,t}function v(e){return null===l||(null===l.cleanups?l.cleanups=[e]:l.cleanups.push(e)),e}function w(){if(this.state&&this.sources){const e=u;u=null,1===this.state?m(this):_(this),u=e}if(s){const e=this.observers?this.observers.length:0;s.sources?(s.sources.push(this),s.sourceSlots.push(e)):(s.sources=[this],s.sourceSlots=[e]),this.observers?(this.observers.push(s),this.observerSlots.push(s.sources.length-1)):(this.observers=[s],this.observerSlots=[s.sources.length-1])}return this.value}function A(e,t,n){return e.comparator&&e.comparator(e.value,t)?t:i?(e.pending===r&&i.push(e),e.pending=t,t):(e.value=t,!e.observers||u&&!e.observers.length||j((()=>{for(let t=0;t<e.observers.length;t+=1){const n=e.observers[t];null,n.observers&&2!==n.state&&P(n),n.state=1,n.pure?u.push(n):c.push(n)}if(u.length>1e6)throw u=[],new Error}),!1),t)}function m(e){if(!e.fn)return;k(e);const t=l,n=s,r=f;s=l=e,function(e,t,n){let r;try{r=e.fn(t)}catch(o){N(o)}(!e.updatedAt||e.updatedAt<=n)&&(e.observers&&e.observers.length?A(e,r):e.value=r,e.updatedAt=n)}(e,e.value,r),s=n,l=t}function S(e,t,n,r){const s={fn:e,state:1,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:t,owner:l,context:null,pure:n};return null===l||l!==o&&(l.owned?l.owned.push(s):l.owned=[s]),s}function O(e){let t,n=1===e.state&&e;if(e.suspense&&y(e.suspense.inFallback))return e.suspense.effects.push(e);for(;e.fn&&(e=e.owner);)2===e.state?t=e:1===e.state&&(n=e,t=void 0);if(t){const e=u;if(u=null,_(t),u=e,!n||1!==n.state)return}n&&m(n)}function j(e,t){if(u)return e();let r=!1;t||(u=[]),c?r=!0:c=[],f++;try{e()}catch(o){N(o)}finally{!function(e){u&&(x(u),u=null);if(e)return;c.length?b((()=>{n(c),c=null})):c=null}(r)}}function x(e){for(let t=0;t<e.length;t++)O(e[t])}function C(e){let t,n=0;for(t=0;t<e.length;t++){const r=e[t];r.user?e[n++]=r:O(r)}const r=e.length;for(t=0;t<n;t++)O(e[t]);for(t=r;t<e.length;t++)O(e[t])}function _(e){e.state=0;for(let t=0;t<e.sources.length;t+=1){const n=e.sources[t];n.sources&&(1===n.state?O(n):2===n.state&&_(n))}}function P(e){for(let t=0;t<e.observers.length;t+=1){const n=e.observers[t];n.state||(n.state=2,n.observers&&P(n))}}function k(e){let t;if(e.sources)for(;e.sources.length;){const t=e.sources.pop(),n=e.sourceSlots.pop(),r=t.observers;if(r&&r.length){const e=r.pop(),o=t.observerSlots.pop();n<r.length&&(e.sourceSlots[o]=n,r[n]=e,t.observerSlots[n]=o)}}if(e.owned){for(t=0;t<e.owned.length;t++)k(e.owned[t]);e.owned=null}if(e.cleanups){for(t=0;t<e.cleanups.length;t++)e.cleanups[t]();e.cleanups=null}e.state=0,e.context=null}function N(e){throw e}const B=Symbol("fallback");function T(e){for(let t=0;t<e.length;t++)e[t]()}function $(e,t){return y((()=>e(t)))}function q(e){const t="fallback"in e&&{fallback:()=>e.fallback};return g(function(e,t,n={}){let r=[],o=[],s=[],i=0,u=t.length>1?[]:null,c=l;return v((()=>T(s))),()=>{let l,f,h=e()||[];return y((()=>{let e,t,d,g,b,y,v,w,A,m=h.length;if(0===m){if(0!==i){{const e=s;setTimeout((()=>T(e)))}s=[],r=[],o=[],i=0,u&&(u=[])}n.fallback&&(r=[B],o[0]=a((e=>(s[0]=e,n.fallback())),c),i=1)}else if(0===i){for(o=new Array(m),f=0;f<m;f++)r[f]=h[f],o[f]=a(p,c);i=m}else{for(d=new Array(m),g=new Array(m),u&&(b=new Array(m)),y=0,v=Math.min(i,m);y<v&&r[y]===h[y];y++);for(v=i-1,w=m-1;v>=y&&w>=y&&r[v]===h[w];v--,w--)d[w]=o[v],g[w]=s[v],u&&(b[w]=u[v]);for(e=new Map,t=new Array(w+1),f=w;f>=y;f--)A=h[f],l=e.get(A),t[f]=void 0===l?-1:l,e.set(A,f);for(l=y;l<=v;l++)A=r[l],f=e.get(A),void 0!==f&&-1!==f?(d[f]=o[l],g[f]=s[l],u&&(b[f]=u[l]),f=t[f],e.set(A,f)):s[l]();for(f=y;f<m;f++)f in d?(o[f]=d[f],s[f]=g[f],u&&(u[f]=b[f],u[f](f))):o[f]=a(p,c);o=o.slice(0,i=m),r=h.slice(0)}return o}));function p(e){if(s[f]=e,u){const[e,n]=d(f);return u[f]=n,t(h[f],e)}return t(h[f])}}}((()=>e.each),e.children,t||void 0))}function D(e){let t=!1;const n=g((()=>e.when),void 0,{equals:(e,n)=>t?e===n:!e==!n});return g((()=>{const r=n();if(r){const n=e.children;return(t="function"==typeof n&&n.length>0)?y((()=>n(r))):n}return e.fallback}))}function F(e,t,n){let r=n.length,o=t.length,l=r,s=0,i=0,u=t[o-1].nextSibling,c=null;for(;s<o||i<l;)if(t[s]!==n[i]){for(;t[o-1]===n[l-1];)o--,l--;if(o===s){const t=l<r?i?n[i-1].nextSibling:n[l-i]:u;for(;i<l;)e.insertBefore(n[i++],t)}else if(l===i)for(;s<o;)c&&c.has(t[s])||e.removeChild(t[s]),s++;else if(t[s]===n[l-1]&&n[i]===t[o-1]){const r=t[--o].nextSibling;e.insertBefore(n[i++],t[s++].nextSibling),e.insertBefore(n[--l],r),t[o]=n[l]}else{if(!c){c=new Map;let e=i;for(;e<l;)c.set(n[e],e++)}const r=c.get(t[s]);if(null!=r)if(i<r&&r<l){let u,f=s,a=1;for(;++f<o&&f<l&&null!=(u=c.get(t[f]))&&u===r+a;)a++;if(a>r-i){const o=t[s];for(;i<r;)e.insertBefore(n[i++],o)}else e.replaceChild(n[i++],t[s++])}else s++;else e.removeChild(t[s++])}}else s++,i++}const M=Symbol("delegated-events");function E(e,t,n){let r;return a((o=>{r=o,H(t,e(),t.firstChild?null:void 0,n)})),()=>{r(),t.textContent=""}}function z(e,t,n){const r=document.createElement("template");r.innerHTML=e;let o=r.content.firstChild;return n&&(o=o.firstChild),o}function L(e,t=window.document){const n=t[M]||(t[M]=new Set);for(let r=0,o=e.length;r<o;r++){const o=e[r];n.has(o)||(n.add(o),t.addEventListener(o,I))}}function H(e,t,n,r){if(void 0===n||r||(r=[]),"function"!=typeof t)return J(e,t,r,n);h((r=>J(e,t(),r,n)),r)}function R(e){return e.cloneNode(!0)}function G(e){return[e,[]]}function I(e){const t=`$$${e.type}`;let n=e.composedPath&&e.composedPath()[0]||e.target;for(e.target!==n&&Object.defineProperty(e,"target",{configurable:!0,value:n}),Object.defineProperty(e,"currentTarget",{configurable:!0,get:()=>n});null!==n;){const r=n[t];if(r){const o=n[`${t}Data`];if(void 0!==o?r(o,e):r(e),e.cancelBubble)return}n=n.host&&n.host!==n&&n.host instanceof Node?n.host:n.parentNode}}function J(e,t,n,r,o){for(;"function"==typeof n;)n=n();if(t===n)return n;const l=typeof t,s=void 0!==r;if(e=s&&n[0]&&n[0].parentNode||e,"string"===l||"number"===l)if("number"===l&&(t=t.toString()),s){let o=n[0];o&&3===o.nodeType?o.data=t:o=document.createTextNode(t),n=U(e,n,r,o)}else n=""!==n&&"string"==typeof n?e.firstChild.data=t:e.textContent=t;else if(null==t||"boolean"===l)n=U(e,n,r);else{if("function"===l)return h((()=>{let o=t();for(;"function"==typeof o;)o=o();n=J(e,o,n,r)})),()=>n;if(Array.isArray(t)){const l=[];if(K(l,t,o))return h((()=>n=J(e,l,n,r,!0))),()=>n;if(0===l.length){if(n=U(e,n,r),s)return n}else Array.isArray(n)?0===n.length?Q(e,l,r):F(e,n,l):null==n||""===n?Q(e,l):F(e,s&&n||[e.firstChild],l);n=l}else if(t instanceof Node){if(Array.isArray(n)){if(s)return n=U(e,n,r,t);U(e,n,null,t)}else null!=n&&""!==n&&e.firstChild?e.replaceChild(t,e.firstChild):e.appendChild(t);n=t}}return n}function K(e,t,n){let r=!1;for(let o=0,l=t.length;o<l;o++){let l,s=t[o];if(s instanceof Node)e.push(s);else if(null==s||!0===s||!1===s);else if(Array.isArray(s))r=K(e,s)||r;else if("string"==(l=typeof s))e.push(document.createTextNode(s));else if("function"===l)if(n){for(;"function"==typeof s;)s=s();r=K(e,Array.isArray(s)?s:[s])||r}else e.push(s),r=!0;else e.push(document.createTextNode(s.toString()))}return r}function Q(e,t,n){for(let r=0,o=t.length;r<o;r++)e.insertBefore(t[r],n)}function U(e,t,n,r){if(void 0===n)return e.textContent="";const o=r||document.createTextNode("");if(t.length){let r=!1;for(let l=t.length-1;l>=0;l--){const s=t[l];if(o!==s){const t=s.parentNode===e;r||l?t&&e.removeChild(s):t?e.replaceChild(o,s):e.insertBefore(o,n)}else r=!0}}else e.insertBefore(o,n);return[o]}const V=Symbol("store-raw"),W=Symbol("store-node"),X=Symbol("store-name");function Y(t,n){let r=t[e];if(!r){Object.defineProperty(t,e,{value:r=new Proxy(t,re)});const n=Object.keys(t),o=Object.getOwnPropertyDescriptors(t);for(let e=0,l=n.length;e<l;e++){const l=n[e];if(o[l].get){const e=o[l].get.bind(r);Object.defineProperty(t,l,{get:e})}}}return r}function Z(e){return null!=e&&"object"==typeof e&&(!e.__proto__||e.__proto__===Object.prototype||Array.isArray(e))}function ee(e,t=new Set){let n,r,o,l;if(n=null!=e&&e[V])return n;if(!Z(e)||t.has(e))return e;if(Array.isArray(e)){Object.isFrozen(e)?e=e.slice(0):t.add(e);for(let n=0,l=e.length;n<l;n++)o=e[n],(r=ee(o,t))!==o&&(e[n]=r)}else{Object.isFrozen(e)?e=Object.assign({},e):t.add(e);const n=Object.keys(e),s=Object.getOwnPropertyDescriptors(e);for(let i=0,u=n.length;i<u;i++)l=n[i],s[l].get||(o=e[l],(r=ee(o,t))!==o&&(e[l]=r))}return e}function te(e){let t=e[W];return t||Object.defineProperty(e,W,{value:t={}}),t}function ne(){const[e,t]=d(void 0,{equals:!1});return e.$=t,e}const re={get(t,n,r){if(n===V)return t;if(n===e)return r;const o=t[n];if(n===W||"__proto__"===n)return o;const l=Z(o);if(s&&("function"!=typeof o||t.hasOwnProperty(n))){let e,r;l&&(e=te(o))&&(r=e._||(e._=ne()),r()),e=te(t),r=e[n]||(e[n]=ne()),r()}return l?Y(o):o},set:()=>!0,deleteProperty:()=>!0,getOwnPropertyDescriptor:function(t,n){const r=Reflect.getOwnPropertyDescriptor(t,n);return!r||r.get||n===e||n===W||n===X||(delete r.value,delete r.writable,r.get=()=>t[e][n]),r}};function oe(e,t,n){if(e[t]===n)return;const r=Array.isArray(e),o=e.length,l=void 0===n,s=r||l===t in e;l?delete e[t]:e[t]=n;let i,u=te(e);(i=u[t])&&i.$(),r&&e.length!==o&&(i=u.length)&&i.$(i,void 0),s&&(i=u._)&&i.$(i,void 0)}function le(e,t,n=[]){let r,o=e;if(t.length>1){r=t.shift();const l=typeof r,s=Array.isArray(e);if(Array.isArray(r)){for(let o=0;o<r.length;o++)le(e,[r[o]].concat(t),[r[o]].concat(n));return}if(s&&"function"===l){for(let o=0;o<e.length;o++)r(e[o],o)&&le(e,[o].concat(t),[o].concat(n));return}if(s&&"object"===l){const{from:o=0,to:l=e.length-1,by:s=1}=r;for(let r=o;r<=l;r+=s)le(e,[r].concat(t),[r].concat(n));return}if(t.length>1)return void le(e[r],t,[r].concat(n));o=e[r],n=[r].concat(n)}let l=t[0];"function"==typeof l&&(l=l(o,n),l===o)||void 0===r&&null==l||(l=ee(l),void 0===r||Z(o)&&Z(l)&&!Array.isArray(l)?function(e,t){const n=Object.keys(t);for(let r=0;r<n.length;r+=1){const o=n[r];oe(e,o,t[o])}}(o,l):oe(e,r,l))}function se(e,t){const n=ee(e||{});return[Y(n),function(...e){b((()=>le(n,e)))}]}export{q as F,D as S,G as a,$ as b,g as c,L as d,se as e,p as f,R as g,h,H as i,v as o,E as r,z as t};
const e=Symbol("solid-proxy"),t={equals:(e,t)=>e===t};let n=x;const r={},o={owned:null,cleanups:null,context:null,owner:null};var l=null;let s=null,i=null,u=null,c=null,f=0;function a(e,t){t&&(l=t);const n=s,r=l,i=0===e.length?o:{owned:null,cleanups:null,context:null,owner:r,attached:!!t};let u;l=i,s=null;try{j((()=>u=e((()=>k(i)))),!0)}finally{s=n,l=r}return u}function d(e,n){n=n?Object.assign({},t,n):t;const o={value:e,observers:null,observerSlots:null,pending:r,comparator:n.equals||void 0};return[w.bind(o),e=>("function"==typeof e&&(e=e(o.pending!==r?o.pending:o.value)),A(o,e))]}function h(e,t,n){m(S(e,t,!1))}function p(e,t,r){n=C;const o=S(e,t,!1);o.user=!0,c&&c.push(o)}function g(e,n,o){o=o?Object.assign({},t,o):t;const l=S(e,n,!0);return l.pending=r,l.observers=null,l.observerSlots=null,l.state=0,l.comparator=o.equals||void 0,m(l),w.bind(l)}function b(e){if(i)return e();let t;const n=i=[];try{t=e()}finally{i=null}return j((()=>{for(let e=0;e<n.length;e+=1){const t=n[e];if(t.pending!==r){const e=t.pending;t.pending=r,A(t,e)}}}),!1),t}function y(e){let t,n=s;return s=null,t=e(),s=n,t}function v(e){return null===l||(null===l.cleanups?l.cleanups=[e]:l.cleanups.push(e)),e}function w(){if(this.state&&this.sources){const e=u;u=null,1===this.state?m(this):_(this),u=e}if(s){const e=this.observers?this.observers.length:0;s.sources?(s.sources.push(this),s.sourceSlots.push(e)):(s.sources=[this],s.sourceSlots=[e]),this.observers?(this.observers.push(s),this.observerSlots.push(s.sources.length-1)):(this.observers=[s],this.observerSlots=[s.sources.length-1])}return this.value}function A(e,t,n){return e.comparator&&e.comparator(e.value,t)?t:i?(e.pending===r&&i.push(e),e.pending=t,t):(e.value=t,!e.observers||u&&!e.observers.length||j((()=>{for(let t=0;t<e.observers.length;t+=1){const n=e.observers[t];null,n.observers&&2!==n.state&&P(n),n.state=1,n.pure?u.push(n):c.push(n)}if(u.length>1e6)throw u=[],new Error}),!1),t)}function m(e){if(!e.fn)return;k(e);const t=l,n=s,r=f;s=l=e,function(e,t,n){let r;try{r=e.fn(t)}catch(o){N(o)}(!e.updatedAt||e.updatedAt<=n)&&(e.observers&&e.observers.length?A(e,r):e.value=r,e.updatedAt=n)}(e,e.value,r),s=n,l=t}function S(e,t,n,r){const s={fn:e,state:1,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:t,owner:l,context:null,pure:n};return null===l||l!==o&&(l.owned?l.owned.push(s):l.owned=[s]),s}function O(e){let t,n=1===e.state&&e;if(e.suspense&&y(e.suspense.inFallback))return e.suspense.effects.push(e);for(;e.fn&&(e=e.owner);)2===e.state?t=e:1===e.state&&(n=e,t=void 0);if(t){const e=u;if(u=null,_(t),u=e,!n||1!==n.state)return}n&&m(n)}function j(e,t){if(u)return e();let r=!1;t||(u=[]),c?r=!0:c=[],f++;try{e()}catch(o){N(o)}finally{!function(e){u&&(x(u),u=null);if(e)return;c.length?b((()=>{n(c),c=null})):c=null}(r)}}function x(e){for(let t=0;t<e.length;t++)O(e[t])}function C(e){let t,n=0;for(t=0;t<e.length;t++){const r=e[t];r.user?e[n++]=r:O(r)}const r=e.length;for(t=0;t<n;t++)O(e[t]);for(t=r;t<e.length;t++)O(e[t])}function _(e){e.state=0;for(let t=0;t<e.sources.length;t+=1){const n=e.sources[t];n.sources&&(1===n.state?O(n):2===n.state&&_(n))}}function P(e){for(let t=0;t<e.observers.length;t+=1){const n=e.observers[t];n.state||(n.state=2,n.observers&&P(n))}}function k(e){let t;if(e.sources)for(;e.sources.length;){const t=e.sources.pop(),n=e.sourceSlots.pop(),r=t.observers;if(r&&r.length){const e=r.pop(),o=t.observerSlots.pop();n<r.length&&(e.sourceSlots[o]=n,r[n]=e,t.observerSlots[n]=o)}}if(e.owned){for(t=0;t<e.owned.length;t++)k(e.owned[t]);e.owned=null}if(e.cleanups){for(t=0;t<e.cleanups.length;t++)e.cleanups[t]();e.cleanups=null}e.state=0,e.context=null}function N(e){throw e}const B=Symbol("fallback");function T(e){for(let t=0;t<e.length;t++)e[t]()}function $(e,t){return y((()=>e(t)))}function q(e){const t="fallback"in e&&{fallback:()=>e.fallback};return g(function(e,t,n={}){let r=[],o=[],s=[],i=0,u=t.length>1?[]:null,c=l;return v((()=>T(s))),()=>{let l,f,h=e()||[];return y((()=>{let e,t,d,g,b,y,v,w,A,m=h.length;if(0===m){if(0!==i){{const e=s;setTimeout((()=>T(e)))}s=[],r=[],o=[],i=0,u&&(u=[])}n.fallback&&(r=[B],o[0]=a((e=>(s[0]=e,n.fallback())),c),i=1)}else if(0===i){for(o=new Array(m),f=0;f<m;f++)r[f]=h[f],o[f]=a(p,c);i=m}else{for(d=new Array(m),g=new Array(m),u&&(b=new Array(m)),y=0,v=Math.min(i,m);y<v&&r[y]===h[y];y++);for(v=i-1,w=m-1;v>=y&&w>=y&&r[v]===h[w];v--,w--)d[w]=o[v],g[w]=s[v],u&&(b[w]=u[v]);for(e=new Map,t=new Array(w+1),f=w;f>=y;f--)A=h[f],l=e.get(A),t[f]=void 0===l?-1:l,e.set(A,f);for(l=y;l<=v;l++)A=r[l],f=e.get(A),void 0!==f&&-1!==f?(d[f]=o[l],g[f]=s[l],u&&(b[f]=u[l]),f=t[f],e.set(A,f)):s[l]();for(f=y;f<m;f++)f in d?(o[f]=d[f],s[f]=g[f],u&&(u[f]=b[f],u[f](f))):o[f]=a(p,c);o=o.slice(0,i=m),r=h.slice(0)}return o}));function p(e){if(s[f]=e,u){const[e,n]=d(f);return u[f]=n,t(h[f],e)}return t(h[f])}}}((()=>e.each),e.children,t||void 0))}function D(e){let t=!1;const n=g((()=>e.when),void 0,{equals:(e,n)=>t?e===n:!e==!n});return g((()=>{const r=n();if(r){const n=e.children;return(t="function"==typeof n&&n.length>0)?y((()=>n(r))):n}return e.fallback}))}function F(e,t,n){let r=n.length,o=t.length,l=r,s=0,i=0,u=t[o-1].nextSibling,c=null;for(;s<o||i<l;)if(t[s]!==n[i]){for(;t[o-1]===n[l-1];)o--,l--;if(o===s){const t=l<r?i?n[i-1].nextSibling:n[l-i]:u;for(;i<l;)e.insertBefore(n[i++],t)}else if(l===i)for(;s<o;)c&&c.has(t[s])||e.removeChild(t[s]),s++;else if(t[s]===n[l-1]&&n[i]===t[o-1]){const r=t[--o].nextSibling;e.insertBefore(n[i++],t[s++].nextSibling),e.insertBefore(n[--l],r),t[o]=n[l]}else{if(!c){c=new Map;let e=i;for(;e<l;)c.set(n[e],e++)}const r=c.get(t[s]);if(null!=r)if(i<r&&r<l){let u,f=s,a=1;for(;++f<o&&f<l&&null!=(u=c.get(t[f]))&&u===r+a;)a++;if(a>r-i){const o=t[s];for(;i<r;)e.insertBefore(n[i++],o)}else e.replaceChild(n[i++],t[s++])}else s++;else e.removeChild(t[s++])}}else s++,i++}const M=Symbol("delegated-events");function E(e,t,n){let r;return a((o=>{r=o,H(t,e(),t.firstChild?null:void 0,n)})),()=>{r(),t.textContent=""}}function z(e,t,n){const r=document.createElement("template");r.innerHTML=e;let o=r.content.firstChild;return n&&(o=o.firstChild),o}function L(e,t=window.document){const n=t[M]||(t[M]=new Set);for(let r=0,o=e.length;r<o;r++){const o=e[r];n.has(o)||(n.add(o),t.addEventListener(o,R))}}function H(e,t,n,r){if(void 0===n||r||(r=[]),"function"!=typeof t)return G(e,t,r,n);h((r=>G(e,t(),r,n)),r)}function R(e){const t=`$$${e.type}`;let n=e.composedPath&&e.composedPath()[0]||e.target;for(e.target!==n&&Object.defineProperty(e,"target",{configurable:!0,value:n}),Object.defineProperty(e,"currentTarget",{configurable:!0,get:()=>n});null!==n;){const r=n[t];if(r){const o=n[`${t}Data`];if(void 0!==o?r(o,e):r(e),e.cancelBubble)return}n=n.host&&n.host!==n&&n.host instanceof Node?n.host:n.parentNode}}function G(e,t,n,r,o){for(;"function"==typeof n;)n=n();if(t===n)return n;const l=typeof t,s=void 0!==r;if(e=s&&n[0]&&n[0].parentNode||e,"string"===l||"number"===l)if("number"===l&&(t=t.toString()),s){let o=n[0];o&&3===o.nodeType?o.data=t:o=document.createTextNode(t),n=K(e,n,r,o)}else n=""!==n&&"string"==typeof n?e.firstChild.data=t:e.textContent=t;else if(null==t||"boolean"===l)n=K(e,n,r);else{if("function"===l)return h((()=>{let o=t();for(;"function"==typeof o;)o=o();n=G(e,o,n,r)})),()=>n;if(Array.isArray(t)){const l=[];if(I(l,t,o))return h((()=>n=G(e,l,n,r,!0))),()=>n;if(0===l.length){if(n=K(e,n,r),s)return n}else Array.isArray(n)?0===n.length?J(e,l,r):F(e,n,l):null==n||""===n?J(e,l):F(e,s&&n||[e.firstChild],l);n=l}else if(t instanceof Node){if(Array.isArray(n)){if(s)return n=K(e,n,r,t);K(e,n,null,t)}else null!=n&&""!==n&&e.firstChild?e.replaceChild(t,e.firstChild):e.appendChild(t);n=t}}return n}function I(e,t,n){let r=!1;for(let o=0,l=t.length;o<l;o++){let l,s=t[o];if(s instanceof Node)e.push(s);else if(null==s||!0===s||!1===s);else if(Array.isArray(s))r=I(e,s)||r;else if("string"==(l=typeof s))e.push(document.createTextNode(s));else if("function"===l)if(n){for(;"function"==typeof s;)s=s();r=I(e,Array.isArray(s)?s:[s])||r}else e.push(s),r=!0;else e.push(document.createTextNode(s.toString()))}return r}function J(e,t,n){for(let r=0,o=t.length;r<o;r++)e.insertBefore(t[r],n)}function K(e,t,n,r){if(void 0===n)return e.textContent="";const o=r||document.createTextNode("");if(t.length){let r=!1;for(let l=t.length-1;l>=0;l--){const s=t[l];if(o!==s){const t=s.parentNode===e;r||l?t&&e.removeChild(s):t?e.replaceChild(o,s):e.insertBefore(o,n)}else r=!0}}else e.insertBefore(o,n);return[o]}const Q=Symbol("store-raw"),U=Symbol("store-node"),V=Symbol("store-name");function W(t,n){let r=t[e];if(!r){Object.defineProperty(t,e,{value:r=new Proxy(t,te)});const n=Object.keys(t),o=Object.getOwnPropertyDescriptors(t);for(let e=0,l=n.length;e<l;e++){const l=n[e];if(o[l].get){const e=o[l].get.bind(r);Object.defineProperty(t,l,{get:e})}}}return r}function X(e){return null!=e&&"object"==typeof e&&(!e.__proto__||e.__proto__===Object.prototype||Array.isArray(e))}function Y(e,t=new Set){let n,r,o,l;if(n=null!=e&&e[Q])return n;if(!X(e)||t.has(e))return e;if(Array.isArray(e)){Object.isFrozen(e)?e=e.slice(0):t.add(e);for(let n=0,l=e.length;n<l;n++)o=e[n],(r=Y(o,t))!==o&&(e[n]=r)}else{Object.isFrozen(e)?e=Object.assign({},e):t.add(e);const n=Object.keys(e),s=Object.getOwnPropertyDescriptors(e);for(let i=0,u=n.length;i<u;i++)l=n[i],s[l].get||(o=e[l],(r=Y(o,t))!==o&&(e[l]=r))}return e}function Z(e){let t=e[U];return t||Object.defineProperty(e,U,{value:t={}}),t}function ee(){const[e,t]=d(void 0,{equals:!1});return e.$=t,e}const te={get(t,n,r){if(n===Q)return t;if(n===e)return r;const o=t[n];if(n===U||"__proto__"===n)return o;const l=X(o);if(s&&("function"!=typeof o||t.hasOwnProperty(n))){let e,r;l&&(e=Z(o))&&(r=e._||(e._=ee()),r()),e=Z(t),r=e[n]||(e[n]=ee()),r()}return l?W(o):o},set:()=>!0,deleteProperty:()=>!0,getOwnPropertyDescriptor:function(t,n){const r=Reflect.getOwnPropertyDescriptor(t,n);return!r||r.get||n===e||n===U||n===V||(delete r.value,delete r.writable,r.get=()=>t[e][n]),r}};function ne(e,t,n){if(e[t]===n)return;const r=Array.isArray(e),o=e.length,l=void 0===n,s=r||l===t in e;l?delete e[t]:e[t]=n;let i,u=Z(e);(i=u[t])&&i.$(),r&&e.length!==o&&(i=u.length)&&i.$(i,void 0),s&&(i=u._)&&i.$(i,void 0)}function re(e,t,n=[]){let r,o=e;if(t.length>1){r=t.shift();const l=typeof r,s=Array.isArray(e);if(Array.isArray(r)){for(let o=0;o<r.length;o++)re(e,[r[o]].concat(t),[r[o]].concat(n));return}if(s&&"function"===l){for(let o=0;o<e.length;o++)r(e[o],o)&&re(e,[o].concat(t),[o].concat(n));return}if(s&&"object"===l){const{from:o=0,to:l=e.length-1,by:s=1}=r;for(let r=o;r<=l;r+=s)re(e,[r].concat(t),[r].concat(n));return}if(t.length>1)return void re(e[r],t,[r].concat(n));o=e[r],n=[r].concat(n)}let l=t[0];"function"==typeof l&&(l=l(o,n),l===o)||void 0===r&&null==l||(l=Y(l),void 0===r||X(o)&&X(l)&&!Array.isArray(l)?function(e,t){const n=Object.keys(t);for(let r=0;r<n.length;r+=1){const o=n[r];ne(e,o,t[o])}}(o,l):ne(e,r,l))}function oe(e,t){const n=Y(e||{});return[W(n),function(...e){b((()=>re(n,e)))}]}export{q as F,D as S,$ as a,oe as b,g as c,L as d,p as e,h as f,H as i,v as o,E as r,z as t};
@kaushalyap
Copy link

The thing is initial load is where this tends to matter the most.

That makes sense due to first impression, comparison to Preact would be awesome in this regard.

All size matters but it is much less felt if at all.

While it may not be an issue for developed countries with decent hardware specs and good network connections, but not to the others.

Also I'm not sure I'd consider it rapid.

I suppose what I intended to say was when you hit inflection point distance between two lines get bigger and bigger, as you said on reddit since solid components are much lighter than Svelte gradient of the line will be smaller which result in "Go far go slow" for Solid. It is interesting to see a graph too.

I'm working on bringing Preact and React in and doing some more comparisons, probably in a separate article mind you.

Please do add preact, react probably would be little below Vue

@ryansolid
Copy link
Author

ryansolid commented Oct 14, 2021

I've posted the article here and added some more analysis: https://dev.to/this-is-learning/javascript-framework-todomvc-size-comparison-504f

I suppose what I intended to say was when you hit inflection point distance between two lines get bigger and bigger, as you said on reddit since solid components are much lighter than Svelte gradient of the line will be smaller which result in "Go far go slow" for Solid. It is interesting to see a graph too.

Yeah the thing is even a subtle difference changes the equation when you are looking that far out. Let's pretend I optimize another 200 bytes off our TodoMVC example, and suddenly the intersection point moves maybe 20 TodoMVCs, (or like 60 components). I think the real take away should be how similar the frameworks are in the working range.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment