Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
Run results for:
hyperlit vs hyperhype vs hyperapp vs react
Go to the benchmark
Embed
Embed Benchmark Result
Run details:
User agent:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
Browser:
Chrome 131
Operating system:
Windows
Device Platform:
Desktop
Date tested:
one year ago
Test name
Executions per second
hyperlit
807.9 Ops/sec
hyperhype
722.1 Ops/sec
hyperapp
978.1 Ops/sec
react
477.2 Ops/sec
HTML Preparation code:
<!DOCTYPE html> <html lang="en"> <head> <script type="module"> import { h, text, app } from "https://unpkg.com/hyperapp" import html from "https://unpkg.com/hyperlit" let p={},m=[],s="http://www.w3.org/2000/svg",c=e=>e,t=m.map,g=Array.isArray,u=t=>t?"string"==typeof t?t:(g(t)?t.map(u).filter(Boolean):Object.keys(t).filter(e=>t[e])).join(" "):"",k=e=>null==e?e:e.key,x=(e,t,n,l,r,o)=>{var i;if("style"===t)for(var a in{...n,...l}){var s=null==l||null==l[a]?"":l[a];"-"===a[0]?e[t].setProperty(a,s):e[t][a]=s}else"o"===t[0]&&"n"===t[1]?(i=t.slice(2),e.events||={},(e.events[i]=l)?n||e.addEventListener(i,r):e.removeEventListener(i,r)):!o&&"list"!==t&&"form"!==t&&t in e?e[t]=l??"":null==l||!1===l?e.removeAttribute(t):e.setAttribute(t,l)},A=(t,n,e)=>{var l,r=t.props||{},o=e||"svg"===t.tag,i=4===t.type?document.createTextNode(t.tag):o?document.createElementNS(s,t.tag):document.createElement(t.tag,{is:r.is});for(l in r)x(i,l,null,r[l],n,o);for(let e=0;e<t.children.length;e++){var a=B(t.children[e]);t.children[e]=a,i.appendChild(A(a,n,o))}return t.node=i},N=(e,p,m,c,g,v)=>{if(m!==c)if(null!=m&&4===m.type&&4===c.type)m.tag!==c.tag&&(p.nodeValue=c.tag);else if(null==m||m.tag!==c.tag)p=e.insertBefore(A(c=B(c),g,v),p),null!=m&&e.removeChild(m.node);else{let n,l,e,r,t=m.props,o=c.props,i=m.children,a=c.children,s=0,u=0,f=i.length-1,d=a.length-1;var h,y=v||"svg"===c.tag;for(h in{...t,...o})("value"===h||"selected"===h||"checked"===h?p:t)[h]!==o[h]&&x(p,h,t[h],o[h],g,y);for(;u<=d&&s<=f&&null!=(e=k(i[s]))&&e===k(a[u]);)N(p,i[s].node,i[s],a[u]=B(a[u++],i[s++]),g,y);for(;u<=d&&s<=f&&null!=(e=k(i[f]))&&e===k(a[d]);)N(p,i[f].node,i[f],a[d]=B(a[d--],i[f--]),g,y);if(s>f)for(;u<=d;)p.insertBefore(A(a[u]=B(a[u++]),g,y),(l=i[s])&&l.node);else if(u>d)for(;s<=f;)p.removeChild(i[s++].node);else{var b,w={},C={};let e,t;for(t=s;t<=f;t++)null!=(e=i[t].key)&&(w[e]=i[t]);for(;u<=d;)e=k(l=i[s]),r=k(a[u]=B(a[u],l)),C[e]||null!=r&&r===k(i[s+1])?(null==e&&p.removeChild(l.node),s++):null==r||2===m.type?(null==e&&(N(p,l?.node,l,a[u],g,y),u++),s++):(e===r?(N(p,l.node,l,a[u],g,y),C[r]=!0,s++):null!=(n=w[r])?(N(p,p.insertBefore(n.node,l?.node),n,a[u],g,y),C[r]=!0):N(p,l?.node,null,a[u],g,y),u++);for(;s<=f;)null==k(l=i[s++])&&p.removeChild(l.node);for(b in w)null==C[b]&&p.removeChild(w[b].node)}}return c.node=p},n=(e,t)=>{for(var n in e)if(e[n]!==t[n])return!0;for(var l in t)if(e[l]!==t[l])return!0},B=(e,t)=>!0!==e&&!1!==e&&e?"function"==typeof e.tag?(t&&null!=t.memo&&!n(t.memo,e.memo)||((t=e.tag(e.memo)).memo=e.memo),t):e:r(""),v=e=>4===e.nodeType?r(e.nodeValue,e):f(e.nodeName.toLowerCase(),p,t.call(e.childNodes,v),2,e),f=(e,{key:t,...n},l,r,o)=>({tag:e,props:n,key:t,children:l,type:r,node:o}),d=e=>e?g(e)?e.map(e=>"string"==typeof e?r(e):e):"string"==typeof e?[r(e)]:[e]:m,l=a=>(o,i)=>{{let[e,t=p,n=m]=[a,g(o)||"string"==typeof o?null:o,d(g(o)||"string"==typeof o?o:i)],{class:l,...r}=t||p;return f(e,{...r,...l?{class:u(l)}:p},d(n))}},r=(e,t)=>f(e,p,m,4,t),e=(e,t)=>({tag:e,memo:t}),o={text:r};for(var i of["div","span","p","a","button","input","form","img","h1","h2","h3","ul","li","table","tr","td","th","select","option","label","textarea","svg","main"])o[i]=l(i);let a=Object.create(null),h=new Proxy(o,{get:(e,t)=>t in e?e[t]:t in a?a[t]:a[t]=l(t)}),y=({node:e,view:t,subscriptions:n,dispatch:l=c,init:r=p})=>{let o=e&&v(e),i=[],a,s,u=e=>{a!==e&&(null==(a=e)&&(l=n=f=c),n&&(i=((t,n,l=m)=>{var r,o,i=[];for(let e=0;e<t.length||e<l.length;e++)r=t[e],o=l[e],i.push(o&&!0!==o?!r||o[0]!==r[0]||((e,t)=>{for(var n in{...e,...t})if("function"==typeof(g(e[n])?e[n][0]:e[n]))t[n]=e[n];else if(e[n]!==t[n])return!0})(o[1],r[1])?[o[0],o[1],(r?.[2](),o[0](n,o[1]))]:r:r?.[2]());return i})(i,l,n(a))),t)&&!s&&requestAnimationFrame(f,s=!0)},f=()=>e=N(e.parentNode,e,o,o=t(a),d,s=!1),d=function(e){l(this.events[e.type],e)};return(l=l((e,t)=>"function"==typeof e?l(e(a,t)):g(e)?"function"==typeof e[0]?l(e[0],e[1]):e.slice(1).map(e=>e&&!0!==e&&(e[0]||e)(l,e[1]),u(e[0])):u(e)))(r),l};export{y as app,e as memo,h as xml}; const { xapp, xmemo, xml} = { xapp: y, xmemo: e, xml: h, }; window.TEST_ITEMS = Array(1000).fill().map((_, i) => `Item ${i}`); window.h = h; window.text = text; window.app = app; window.html = html; window.xapp = xapp; window.xmemo = xmemo; window.xml = xml; const {main, h1, button, ul, li} = xml; </script> <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script> <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> </head> <body> <main id="app"></main> </body> </html>
Tests:
hyperlit
const state = { count: 0, items: window.TEST_ITEMS.slice(0, 800), reversed: false } const actions = { update: state => ({ ...state, count: state.count + 1, items: state.reversed ? [...state.items].reverse() : [...state.items].sort(() => Math.random() - 0.5), reversed: !state.reversed }) } app({ init: state, view: state => html` <main> <h1>${state.count}</h1> <button onclick=${() => actions.update(state)}>Update</button> <ul> ${state.items.map(item => html`<li key=${item}>${item} - ${state.count}</li>` )} </ul> </main> `, node: document.getElementById("app") })
hyperhype
const state = { count: 0, items: window.TEST_ITEMS.slice(0, 800), reversed: false }; const actions = { update: (state) => ({ ...state, count: state.count + 1, items: state.reversed ? [...state.items].reverse() : [...state.items].sort(() => Math.random() - 0.5), reversed: !state.reversed }), }; xapp({ init: state, view: (state) => main({}, [ h1({}, String(state.count)), button({ onclick: actions.update }, "Update"), ul( {}, state.items.map((item) => li({ key: item }, `${item} - ${state.count}`), ), ), ]), node: document.getElementById("app") });
hyperapp
const state = { count: 0, items: window.TEST_ITEMS.slice(0, 800), reversed: false } const actions = { update: state => ({ ...state, count: state.count + 1, items: state.reversed ? [...state.items].reverse() : [...state.items].sort(() => Math.random() - 0.5), reversed: !state.reversed }) } app({ init: state, view: state => h("main", {}, [ h("h1", {}, text(state.count)), h("button", { onclick: actions.update }, text("Update")), h("ul", {}, state.items.map(item => h("li", { key: item }, text(`${item} - ${state.count}`)) ) ) ]), node: document.getElementById("app") })
react
const { useState } = React; function App() { const [state, setState] = useState({ count: 0, items: window.TEST_ITEMS.slice(0, 800), reversed: false }); const update = () => { setState(state => ({ ...state, count: state.count + 1, items: state.reversed ? [...state.items].reverse() : [...state.items].sort(() => Math.random() - 0.5), reversed: !state.reversed })); }; return React.createElement('main', null, [ React.createElement('h1', { key: 'h1' }, state.count), React.createElement('button', { key: 'button', onClick: update }, 'Update'), React.createElement('ul', { key: 'ul' }, state.items.map(item => React.createElement('li', { key: item }, `${item} - ${state.count}`) ) ) ]); } ReactDOM.render( React.createElement(App), document.getElementById('app') );