/*global coverage, ENABLE_PERFORMANCE, NODE_ENV*/ /*eslint no-console:0*/ /** @jsx h */ let { h, Component, render } = require(NODE_ENV==='production' ? '../../dist/preact.min.js' : '../../src/preact'); const MULTIPLIER = ENABLE_PERFORMANCE ? (coverage ? 5 : 1) : 999999; let now = typeof performance!=='undefined' && performance.now ? () => performance.now() : () => +new Date(); function loop(iter, time) { let start = now(), count = 0; while ( now()-start < time ) { count++; iter(); } return count; } function benchmark(iter, callback) { let a = 0; function noop() { try { a++; } finally { a += Math.random(); } } // warm for (let i=3; i--; ) noop(), iter(); let count = 5, time = 200, passes = 0, noops = loop(noop, time), iterations = 0; function next() { iterations += loop(iter, time); setTimeout(++passes===count ? done : next, 10); } function done() { let ticks = Math.round(noops / iterations * count), hz = iterations / count / time * 1000, message = `${hz|0}/s (${ticks} ticks)`; callback({ iterations, noops, count, time, ticks, hz, message }); } next(); } describe('performance', function() { let scratch; this.timeout(10000); before( () => { if (coverage) { console.warn('WARNING: Code coverage is enabled, which dramatically reduces performance. Do not pay attention to these numbers.'); } scratch = document.createElement('div'); (document.body || document.documentElement).appendChild(scratch); }); beforeEach( () => { scratch.innerHTML = ''; }); after( () => { scratch.parentNode.removeChild(scratch); scratch = null; }); it('should rerender without changes fast', done => { let jsx = (

a {'b'} c {0} d

{}}>
); let root; benchmark( () => { root = render(jsx, scratch, root); }, ({ ticks, message }) => { console.log(`PERF: empty diff: ${message}`); expect(ticks).to.be.below(350 * MULTIPLIER); done(); }); }); it('should rerender repeated trees fast', done => { class Header extends Component { render() { return (

a {'b'} c {0} d

); } } class Form extends Component { render() { return (
{}}>
); } } class ButtonBar extends Component { render() { return ( ); } } class Button extends Component { render(props) { return ); }, ({ ticks, message }) => { console.log(`PERF: large VTree: ${message}`); expect(ticks).to.be.below(2000 * MULTIPLIER); done(); }); }); });