mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
@@ -49,7 +49,6 @@ matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- env: TEST_TYPE=test:coverage
|
||||
- env: TEST_TYPE=perf:full
|
||||
- env: TEST_TYPE=test:webdriver:saucelabs:modern
|
||||
- env: TEST_TYPE=test:webdriver:saucelabs BROWSER_NAME=ie11
|
||||
- env: TEST_TYPE=test:webdriver:saucelabs BROWSER_NAME=ie10
|
||||
|
||||
@@ -24,7 +24,6 @@ module.exports = function(grunt) {
|
||||
populist: require('./grunt/config/populist')(grunt),
|
||||
connect: require('./grunt/config/server')(grunt),
|
||||
'webdriver-jasmine': require('./grunt/config/webdriver-jasmine'),
|
||||
'webdriver-perf': require('./grunt/config/webdriver-perf'),
|
||||
npm: require('./grunt/config/npm'),
|
||||
clean: [
|
||||
'./build',
|
||||
@@ -79,8 +78,6 @@ module.exports = function(grunt) {
|
||||
|
||||
grunt.registerMultiTask('webdriver-jasmine', webdriverJasmineTasks);
|
||||
|
||||
grunt.registerMultiTask('webdriver-perf', require('./grunt/tasks/webdriver-perf'));
|
||||
|
||||
grunt.registerMultiTask('npm', npmTask);
|
||||
|
||||
grunt.registerTask('npm-react:release', npmReactTasks.buildRelease);
|
||||
@@ -119,14 +116,6 @@ module.exports = function(grunt) {
|
||||
'version-check',
|
||||
'browserify:withCodeCoverageLogging'
|
||||
]);
|
||||
grunt.registerTask('build:perf', [
|
||||
'jsx:normal',
|
||||
'version-check',
|
||||
'browserify:transformer',
|
||||
'browserify:basic',
|
||||
'browserify:min',
|
||||
'download-previous-version'
|
||||
]);
|
||||
grunt.registerTask('build:test', [
|
||||
'delete-build-modules',
|
||||
'jsx:test',
|
||||
@@ -153,12 +142,6 @@ module.exports = function(grunt) {
|
||||
'webdriver-jasmine:local'
|
||||
]);
|
||||
|
||||
grunt.registerTask('perf:webdriver:phantomjs', [
|
||||
'connect',
|
||||
'webdriver-phantomjs',
|
||||
'webdriver-perf:local'
|
||||
]);
|
||||
|
||||
grunt.registerTask('test:full', [
|
||||
'build:test',
|
||||
'build:basic',
|
||||
@@ -173,20 +156,6 @@ module.exports = function(grunt) {
|
||||
'webdriver-jasmine:saucelabs_chrome'
|
||||
]);
|
||||
|
||||
grunt.registerTask('perf:full', [
|
||||
'build:perf',
|
||||
|
||||
'connect',
|
||||
'webdriver-phantomjs',
|
||||
'webdriver-perf:local',
|
||||
|
||||
'sauce-tunnel',
|
||||
'webdriver-perf:saucelabs_firefox',
|
||||
'webdriver-perf:saucelabs_chrome',
|
||||
'webdriver-perf:saucelabs_ie11',
|
||||
'webdriver-perf:saucelabs_ie8'
|
||||
]);
|
||||
|
||||
grunt.registerTask('test:webdriver:saucelabs', [
|
||||
'build:test',
|
||||
'build:basic',
|
||||
@@ -251,7 +220,6 @@ module.exports = function(grunt) {
|
||||
grunt.task.run('build:test', 'build:basic', 'test:webdriver:phantomjs');
|
||||
}
|
||||
});
|
||||
grunt.registerTask('perf', ['build:perf', 'perf:webdriver:phantomjs']);
|
||||
grunt.registerTask('npm:test', ['build', 'npm:pack']);
|
||||
|
||||
// Optimized build task that does all of our builds. The subtasks will be run
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var grunt = require('grunt');
|
||||
var path = require('path');
|
||||
|
||||
var tests = grunt.file.expand(path.join(__dirname, '/../../perf/tests/*'));
|
||||
|
||||
var maxTime = 5;
|
||||
|
||||
var reactVersions = [
|
||||
'edge',
|
||||
'previous'
|
||||
];
|
||||
|
||||
var params = []
|
||||
.concat('headless=false')
|
||||
.concat('maxTime=' + maxTime)
|
||||
.concat(tests
|
||||
.map(function(testPath) {
|
||||
return testPath.split(/tests./i).reverse()[0];
|
||||
})
|
||||
.map(encodeURIComponent)
|
||||
.map(function(filename) {
|
||||
return 'test=' + filename;
|
||||
})
|
||||
)
|
||||
.concat(reactVersions
|
||||
.map(encodeURIComponent)
|
||||
.map(function(version) {
|
||||
return 'react=' + version;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
module.exports = require('./webdriver-all')({
|
||||
|
||||
url: 'http://127.0.0.1:9999/perf/index.html?' + params.join('&'),
|
||||
|
||||
isDoneTimeout: 15 * 60 * 1000,
|
||||
|
||||
onStart: function() {
|
||||
grunt.event.on('perf results', function(results) {
|
||||
console.log(results);
|
||||
});
|
||||
},
|
||||
|
||||
onComplete: function(completedTestKeys) {
|
||||
grunt.verbose.writeln('onComplete ' + JSON.stringify(completedTestKeys));
|
||||
},
|
||||
|
||||
onError: function(error) {
|
||||
grunt.fatal(error);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1,20 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var grunt = require('grunt');
|
||||
|
||||
module.exports = function() {
|
||||
return require('./webdriver-all').call(this, function(config, wd, browser) {
|
||||
if (!config.isDoneTimeout) {
|
||||
grunt.verbose.writeln('Expected isDoneTimeout config, using default value');
|
||||
}
|
||||
grunt.verbose.writeln('isDoneTimeout:' + config.isDoneTimeout);
|
||||
return browser
|
||||
.waitFor(wd.asserters.jsCondition('window.isDone === false'), 5e3, 50)
|
||||
.fail(function(error) {
|
||||
throw Error('The test page didn\'t load properly. ' + error);
|
||||
})
|
||||
.waitFor(wd.asserters.jsCondition('window.isDone === true'), config.isDoneTimeout || 30e3, 1e3)
|
||||
.waitFor(wd.asserters.jsCondition('window.postDataToURL.running <= 0'), 30e3, 500)
|
||||
.eval('window.completedTestKeys || window._unhandledError');
|
||||
});
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
globals:
|
||||
document: true
|
||||
window: true
|
||||
Benchmark: true
|
||||
React: true
|
||||
_rootNode: true
|
||||
todolist: true
|
||||
_app: true
|
||||
_todo1: true
|
||||
_todo2: true
|
||||
_todo3: true
|
||||
_timesToRun: true
|
||||
setState: true
|
||||
|
||||
rules:
|
||||
strict: false
|
||||
no-undef: false
|
||||
no-unused-vars: false
|
||||
block-scoped-var: false
|
||||
consistent-return: false
|
||||
no-shadow: false
|
||||
@@ -1,67 +0,0 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Perf Tests</title>
|
||||
|
||||
<script>
|
||||
window.onerror = function(error){
|
||||
window._unhandledError = error;
|
||||
window.isDone = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script src="./lib/perf-test-runner.browser.js"></script>
|
||||
<script> perfRunner.Polyfill(); </script>
|
||||
<script src="../build/react.js"></script>
|
||||
<script src="../build/JSXTransformer.js"></script>
|
||||
<script src="../test/lib/postDataToURL.browser.js"></script>
|
||||
<script src="./lib/BrowserPerfRunnerContext.react.js"></script>
|
||||
<script src="./lib/BrowserPerfRunnerApp.react.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
var tests = [
|
||||
"sanity.js",
|
||||
"todolist-mount.js",
|
||||
"todolist-edit.js",
|
||||
"todolist-add.js",
|
||||
"todolist-do-stuff.js",
|
||||
"setState-callback-5.js",
|
||||
"setState-callback.js",
|
||||
"basic-div.js",
|
||||
"basic-unmount.js",
|
||||
"propTypes.js",
|
||||
"renderComponent-basic.js",
|
||||
"shouldComponentUpdate.js",
|
||||
];
|
||||
|
||||
var reactVersions = [
|
||||
'edge',
|
||||
'builds/master/latest'
|
||||
];
|
||||
|
||||
window.onload = function(){
|
||||
window.isDone = false;
|
||||
|
||||
React.render(
|
||||
BrowserPerfRunnerApp({
|
||||
headless: perfRunner.getQueryParamArrayOrDefault('headless', [false])[0],
|
||||
react: perfRunner.getQueryParamArrayOrDefault('react', reactVersions),
|
||||
tests: perfRunner.getQueryParamArrayOrDefault('test', tests),
|
||||
maxTime: perfRunner.getQueryParamArrayOrDefault('maxTime', [5])[0],
|
||||
onCompleteEach: function(results){
|
||||
console.log('onCompleteEach', results);
|
||||
postDataToURL({type:'perf', message:results}, '/reportTestResults');
|
||||
},
|
||||
onError: function(error){
|
||||
window._unhandledError = error;
|
||||
},
|
||||
onComplete: function(results){
|
||||
window.completedTestKeys = Object.keys(results);
|
||||
window.isDone = true;
|
||||
}
|
||||
}),
|
||||
document.body
|
||||
);
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -1,219 +0,0 @@
|
||||
var BrowserPerfRunnerApp = React.createClass({
|
||||
|
||||
propTypes: {
|
||||
tests: React.PropTypes.array.isRequired,
|
||||
react: React.PropTypes.array.isRequired,
|
||||
maxTime: React.PropTypes.number,
|
||||
onCompleteEach: React.PropTypes.func,
|
||||
onComplete: React.PropTypes.func,
|
||||
onError: React.PropTypes.func,
|
||||
headless: React.PropTypes.bool
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
var queue = [];
|
||||
this.props.tests.forEach(function(testName) {
|
||||
this.props.react.forEach(function(version) {
|
||||
queue.push({
|
||||
test: testName,
|
||||
react: version
|
||||
});
|
||||
}, this);
|
||||
}, this);
|
||||
return {
|
||||
queue: queue,
|
||||
results: {}
|
||||
};
|
||||
},
|
||||
|
||||
handleResults: function(results) {
|
||||
this.state.results[results.test + '@' + results.react] = results;
|
||||
this.replaceState(this.state);
|
||||
},
|
||||
|
||||
handleComplete: function(queueItem) {
|
||||
queueItem.completed = true;
|
||||
|
||||
if (!this.props.onCompleteEach) {
|
||||
return;
|
||||
}
|
||||
// Can't get the resultsForAllVersions if there are still some queued
|
||||
var incompleteCount = 0;
|
||||
for (var index = this.state.queue.length; --index >= 0;) {
|
||||
if (this.state.queue[index].completed) {
|
||||
continue;
|
||||
}
|
||||
if (this.state.queue[index].test === queueItem.test) {
|
||||
return;
|
||||
}
|
||||
incompleteCount++;
|
||||
}
|
||||
var resultsForAllVersions = Object.keys(this.state.results)
|
||||
.filter(function(key) {
|
||||
return key.indexOf(queueItem.test) === 0;
|
||||
})
|
||||
.map(function(key) {
|
||||
return this.state.results[key];
|
||||
}, this);
|
||||
this.props.onCompleteEach(resultsForAllVersions);
|
||||
|
||||
if (this.props.onComplete && incompleteCount === 0) {
|
||||
this.props.onComplete(this.state.results);
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var grid = null;
|
||||
|
||||
if (!this.props.headless) {
|
||||
grid = GridViewTable({
|
||||
rows: this.props.tests,
|
||||
cols: this.props.react,
|
||||
renderCell: BrowserPerfRunnerApp.renderBenchmarkCell,
|
||||
value: this.state.results
|
||||
});
|
||||
}
|
||||
|
||||
return React.DOM.div(null,
|
||||
BenchmarkQueue({
|
||||
initialQueue: this.state.queue,
|
||||
onChange: this.handleResults,
|
||||
maxTime: this.props.maxTime,
|
||||
onCompleteEach: this.handleComplete,
|
||||
onError: this.props.onError
|
||||
}),
|
||||
grid
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
BrowserPerfRunnerApp.renderBenchmarkCell = function(props, row, col) {
|
||||
if (col == null && row == null) {
|
||||
return React.DOM.th(null);
|
||||
}
|
||||
if (row == null) {
|
||||
return React.DOM.th({style:{verticalAlign:'top', textAlign:'center'}}, col);
|
||||
}
|
||||
|
||||
var benchmarks = Object.keys(props.value)
|
||||
.filter(function(key) {
|
||||
return key.indexOf(row) === 0;
|
||||
})
|
||||
.map(function(key) {
|
||||
return props.value[key];
|
||||
})
|
||||
.filter(function(benchmark) {
|
||||
return benchmark && !benchmark.isRunning && benchmark.stats;
|
||||
});
|
||||
|
||||
if (col == null) {
|
||||
return React.DOM.th({style:{verticalAlign:'top', textAlign:'right'}},
|
||||
React.DOM.a({href:'?test=' + row}, benchmarks[0] && benchmarks[0].name || row)
|
||||
);
|
||||
}
|
||||
|
||||
var key = row + '@' + col;
|
||||
var benchmark = props.value[key];
|
||||
if (!(benchmark && benchmark.stats)) {
|
||||
return React.DOM.td({key:key});
|
||||
}
|
||||
|
||||
|
||||
var colors = [
|
||||
'000000',
|
||||
'AA0000',
|
||||
'00AA00',
|
||||
'AA5500',
|
||||
'0000AA',
|
||||
'AA00AA',
|
||||
'00AAAA',
|
||||
'AAAAAA',
|
||||
|
||||
'555555',
|
||||
'FF5555',
|
||||
'55FF55',
|
||||
'FFFF55',
|
||||
'5555FF',
|
||||
'FF55FF',
|
||||
'55FFFF',
|
||||
'FFFFFF'
|
||||
];
|
||||
|
||||
function chartValue(value) {
|
||||
return Math.round(valueFromRangeToRange(value, chartValue.min, chartValue.max, 0, 100));
|
||||
}
|
||||
chartValue.min = Math.min.apply(Math, benchmarks.map(function(benchmark) {
|
||||
return Math.min.apply(Math, benchmark.stats.sample);
|
||||
}));
|
||||
chartValue.max = Math.max.apply(Math, benchmarks.map(function(benchmark) {
|
||||
return Math.max.apply(Math, benchmark.stats.sample);
|
||||
}));
|
||||
|
||||
var means = benchmarks.map(function(benchmark) {
|
||||
return benchmark.stats.mean;
|
||||
});
|
||||
benchmarks.forEach(function(benchmark) {
|
||||
benchmark.isTheWinner = benchmark.stats.mean <= Math.min.apply(Math, means);
|
||||
});
|
||||
|
||||
var chartValues = benchmarks.map(function(benchmark) {
|
||||
// benchmark.stats.sample.sort(function(a,b) {return b - a;});
|
||||
return benchmark.stats.sample.map(chartValue).join(',');
|
||||
}).join('|');
|
||||
|
||||
return (
|
||||
React.DOM.td({key:key, style:{textAlign:'center', width:234, verticalAlign:'top'}},
|
||||
benchmark.error && benchmark.error.message || '',
|
||||
React.DOM.div({style: benchmark.isTheWinner ? {backgroundColor:'#0A5', color:'#AFA'} : {backgroundColor:'transparent', color:'inherit'}},
|
||||
Math.round(1 / benchmark.stats.mean * 100) / 100, ' op/s ',
|
||||
React.DOM.strong(null, Math.round(benchmark.stats.mean * 1000 * 100) / 100, ' ms/op '),
|
||||
React.DOM.small(null, '(±' + (Math.round(benchmark.stats.rme * 10) / 10) + '%)')
|
||||
),
|
||||
benchmark.isRunning && 'Running' || React.DOM.img({
|
||||
style: {
|
||||
borderWidth: 2,
|
||||
borderStyle: 'solid',
|
||||
color: '#' + colors[benchmarks.indexOf(benchmark)]
|
||||
},
|
||||
width: 230,
|
||||
height: 50,
|
||||
src: 'https://chart.googleapis.com/chart?cht=ls&chs=460x100&chd=t:' + chartValues + '&chco=' + colors.join(',')
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
function valueFromRangeToRange(value, fromMin, fromMax, toMin, toMax) {
|
||||
var fromRange = fromMax - fromMin;
|
||||
var toRange = toMax - toMin;
|
||||
return (((value - fromMin) * toRange) / fromRange) + toMin;
|
||||
}
|
||||
|
||||
var GridViewTable = React.createClass({
|
||||
|
||||
propTypes: {
|
||||
rows: React.PropTypes.array.isRequired,
|
||||
cols: React.PropTypes.array.isRequired,
|
||||
renderCell: React.PropTypes.func.isRequired
|
||||
},
|
||||
|
||||
_renderCell: function(col) {
|
||||
return this.props.renderCell({value:this.props.value}, this._row, col);
|
||||
},
|
||||
|
||||
_renderRow: function(row) {
|
||||
this._row = row;
|
||||
return React.DOM.tr({key:row},
|
||||
this._renderCell(null, 0),
|
||||
this.props.cols.map(this._renderCell, this)
|
||||
);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return React.DOM.table(null,
|
||||
this._renderRow(null, 0),
|
||||
this.props.rows.map(this._renderRow, this)
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1,201 +0,0 @@
|
||||
var BenchmarkQueue = React.createClass({
|
||||
propTypes: {
|
||||
debug: React.PropTypes.bool,
|
||||
onChange: React.PropTypes.func.isRequired,
|
||||
initialQueue: React.PropTypes.array.isRequired,
|
||||
maxTime: React.PropTypes.number,
|
||||
onCompleteEach: React.PropTypes.func,
|
||||
onError: React.PropTypes.func
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
maxTime: 5
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
queue: this.props.initialQueue.slice()
|
||||
};
|
||||
},
|
||||
|
||||
setItemState: function(state) {
|
||||
state.test = this.state.queue[0].test;
|
||||
state.react = this.state.queue[0].react;
|
||||
this.props.onChange(state);
|
||||
},
|
||||
|
||||
handleContextReady: function(window) {
|
||||
var benchmark = window.Benchmark(window.exports);
|
||||
benchmark.options.maxTime = this.props.maxTime; //DEBUG
|
||||
|
||||
var itemState = {
|
||||
testRunnerURL: window.location.href,
|
||||
|
||||
name: window.exports.name,
|
||||
platform: window.Benchmark.platform.description,
|
||||
reactVersion: window.React.version,
|
||||
|
||||
isMinified: (function() {
|
||||
var code = window.React.render.toString();
|
||||
return code.indexOf(',') - code.indexOf('(') <= 2;
|
||||
}())
|
||||
};
|
||||
|
||||
this.setItemState(itemState);
|
||||
|
||||
var self = this;
|
||||
benchmark.on('start error cycle complete', function() {
|
||||
var stats = JSON.parse(JSON.stringify(benchmark.stats));
|
||||
itemState.stats = stats;
|
||||
itemState.isRunning = benchmark.running;
|
||||
itemState.error = benchmark.error;
|
||||
self.setItemState(itemState);
|
||||
});
|
||||
if (this.props.onError) {
|
||||
benchmark.on('error', this.props.onError);
|
||||
}
|
||||
benchmark.on('complete', function() {
|
||||
var queue = self.state.queue.slice();
|
||||
var queueItem = queue.shift();
|
||||
if (self.props.onCompleteEach) {
|
||||
self.props.onCompleteEach(queueItem);
|
||||
}
|
||||
self.setState({queue:queue});
|
||||
});
|
||||
benchmark.run({async:true});
|
||||
},
|
||||
|
||||
shouldComponentUpdate: function(nextProps, nextState) {
|
||||
return nextState.queue.length < this.state.queue.length;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (!(this.state.queue && this.state.queue.length > 0)) {
|
||||
return React.DOM.div({style:{display:'none'}});
|
||||
}
|
||||
return BrowserPerfRunnerContext({
|
||||
debug: this.props.debug,
|
||||
test: this.state.queue[0].test,
|
||||
react: this.state.queue[0].react,
|
||||
onReady: this.handleContextReady
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var BrowserPerfRunnerContext = React.createClass({
|
||||
|
||||
propTypes: {
|
||||
debug: React.PropTypes.bool,
|
||||
test: function(object, key) {
|
||||
React.PropTypes.string.isRequired(object, key);
|
||||
if (/\.jsx?$/i.test(object[key])) {
|
||||
return;
|
||||
}
|
||||
throw Error('Expected `' + key + '` to be a test file name with extension `.js` or `.jsx`');
|
||||
},
|
||||
react: function(object, key) {
|
||||
React.PropTypes.string.isRequired(object, key);
|
||||
if (/^(?:builds\/.+|edge|previous|(?:\d+\.){2}\d+)$/.test(object[key])) {
|
||||
return;
|
||||
}
|
||||
throw Error('Expected `' + key + '` prop to be a valid react version string, build string or \'edge\' or \'previous\'');
|
||||
},
|
||||
onReady: React.PropTypes.func.isRequired
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
testRunnerURL:'about:blank'
|
||||
};
|
||||
},
|
||||
|
||||
// _handleFrameError: function(error) {
|
||||
// console.error('BrowserPerfRunnerContext', error);
|
||||
// },
|
||||
//
|
||||
// _handleFrameLoad: function(event) {
|
||||
// console.log('BrowserPerfRunnerContext', event);
|
||||
// },
|
||||
//
|
||||
_handleMessage: function(event) {
|
||||
if (location.href.indexOf(event.origin) !== 0) {
|
||||
return console.debug('BrowserPerfRunnerContext#_handleMessage ignored message from ' + event.origin);
|
||||
}
|
||||
if (event.source.location.href.indexOf(this.state.testRunnerURL) === -1) {
|
||||
return console.debug('BrowserPerfRunnerContext#_handleMessage ignored message from ' + event.source.location.href);
|
||||
}
|
||||
if (event.data !== 'Ready!') {
|
||||
return console.debug('BrowserPerfRunnerContext#_handleMessage ignored message ' + JSON.stringify(event.data));
|
||||
}
|
||||
this.props.onReady(event.source);
|
||||
},
|
||||
|
||||
_getTestRunnerURL: function(props) {
|
||||
return 'runner.html' +
|
||||
'?' +
|
||||
'debug=' + (props.debug ? 1 : 0) +
|
||||
'&' +
|
||||
'react=' + encodeURIComponent(props.react) +
|
||||
'&' +
|
||||
'test=' + encodeURIComponent(props.test);
|
||||
},
|
||||
|
||||
_renderState: function(props) {
|
||||
return {
|
||||
testRunnerURL: this._getTestRunnerURL(props)
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
var node = this.refs.iframe.getDOMNode();
|
||||
// node.onload = this._handleFrameLoad;
|
||||
// node.onerror = this._handleFrameError;
|
||||
if (window.addEventListener) {
|
||||
window.addEventListener('message', this._handleMessage, false);
|
||||
} else if (window.attachEvent) {
|
||||
window.attachEvent('onmessage', this._handleMessage);
|
||||
} else {
|
||||
throw Error('cannot attach onmessage listener');
|
||||
}
|
||||
this.setState(this._renderState(this.props));
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
if (window.removeEventListener) {
|
||||
window.removeEventListener('message', this._handleMessage);
|
||||
} else if (window.detachEvent) {
|
||||
window.detachEvent('onmessage', this._handleMessage);
|
||||
} else {
|
||||
throw Error('cannot detach onmessage listener');
|
||||
}
|
||||
this.refs.iframe.getDOMNode().src = '';
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(nextProps) {
|
||||
this.setState(this._renderState(nextProps));
|
||||
},
|
||||
|
||||
shouldComponentUpdate: function(nextProps, nextState) {
|
||||
return nextState.testRunnerURL !== this.state.testRunnerURL;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
React.DOM.iframe({
|
||||
ref: 'iframe',
|
||||
name: 'BrowserPerfRunnerContextFrame',
|
||||
style: this.style,
|
||||
src: this.state.testRunnerURL
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
style: {
|
||||
position: 'absolute',
|
||||
right: '100%',
|
||||
bottom: '100%'
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1,224 +0,0 @@
|
||||
if (typeof console === 'undefined') {
|
||||
console = {
|
||||
log: function() {},
|
||||
warn: function() {},
|
||||
error: function() {},
|
||||
debug: function() {}
|
||||
};
|
||||
}
|
||||
|
||||
var perfRunner;
|
||||
if (typeof exports === 'object') {
|
||||
perfRunner = exports;
|
||||
} else {
|
||||
perfRunner = {};
|
||||
}
|
||||
|
||||
perfRunner.assert = function(test, message) {
|
||||
if (typeof test === 'function') {
|
||||
test = test();
|
||||
}
|
||||
if (test) {
|
||||
return;
|
||||
}
|
||||
throw Error(message);
|
||||
};
|
||||
|
||||
perfRunner.WriteScript = function(props) {
|
||||
var type = '';
|
||||
if (props.jsx) {
|
||||
type = ' type=\'text/jsx\'';
|
||||
}
|
||||
var src = props.src;
|
||||
if (!props.cache) {
|
||||
src += src.indexOf('?') === -1 ? '?_' : '&_';
|
||||
src += perfRunner.WriteScript.cacheBust;
|
||||
}
|
||||
document.write('<script' + type + ' src=\'' + src + '\'><\/script>');
|
||||
};
|
||||
perfRunner.WriteScript.cacheBust = (+new Date()).toString(36);
|
||||
|
||||
perfRunner.WriteReactLibScript = function(params) {
|
||||
var src;
|
||||
var minSuffix;
|
||||
if (params.debug) {
|
||||
minSuffix = '';
|
||||
} else {
|
||||
minSuffix = '.min';
|
||||
}
|
||||
|
||||
if (params.version && typeof params.version !== 'string') {
|
||||
throw TypeError('Expected \'version\' to be a string');
|
||||
}
|
||||
|
||||
if (params.version === 'edge' || !params.version) {
|
||||
console.log('React edge (local)');
|
||||
perfRunner.WriteScript({src:'../build/react' + minSuffix + '.js'});
|
||||
perfRunner.WriteScript({src:'../build/JSXTransformer.js'});
|
||||
} else if (params.version === 'previous') {
|
||||
console.log('React previous (local)');
|
||||
perfRunner.WriteScript({cache:true, src:'../build/react-previous' + minSuffix + '.js'});
|
||||
perfRunner.WriteScript({cache:true, src:'../build/JSXTransformer-previous.js'});
|
||||
} else if (params.version.indexOf('builds/') === 0) {
|
||||
perfRunner.WriteScript({cache:true, src:'http://react.zpao.com/' + params.version + '/react' + minSuffix + '.js'});
|
||||
perfRunner.WriteScript({cache:true, src:'http://react.zpao.com/' + params.version + '/JSXTransformer.js'});
|
||||
} else {
|
||||
console.log('React ' + params.version);
|
||||
perfRunner.WriteScript({cache:true, src:'http://fb.me/react-' + params.version + minSuffix + '.js'});
|
||||
perfRunner.WriteScript({cache:true, src:'http://fb.me/JSXTransformer-' + params.version + '.js'});
|
||||
}
|
||||
if (params.debug) {
|
||||
console.warn('Loading the unminified build of React, performance may suffer.');
|
||||
console.warn('Load \'' + location.href.replace(/\bdebug=\w+&?|&\bdebug=\w+/ig, '') + '\' for better perf.');
|
||||
} else {
|
||||
console.warn('Loading the minified build of React, debugging may be harder.');
|
||||
console.warn('Load \'' + location.href.replace(/\bdebug=\w+&?|&\bdebug=\w+/ig, '') + '&debug=1' + '\' for easier debugging.');
|
||||
}
|
||||
};
|
||||
|
||||
perfRunner.WriteTestScript = function(params) {
|
||||
if (Array.isArray(params.test)) {
|
||||
return params.test
|
||||
.map(function(test) {
|
||||
return {
|
||||
test:test
|
||||
};
|
||||
})
|
||||
.map(perfRunner.WriteTestScript);
|
||||
}
|
||||
perfRunner.assert(params.test.indexOf('..') === -1, 'no relative paths allowed');
|
||||
return perfRunner.WriteScript({jsx:true, src: './tests/' + params.test});
|
||||
};
|
||||
|
||||
perfRunner.getQueryParamArray = function(key) {
|
||||
var values;
|
||||
var queryString = location.search.substr(1);
|
||||
var _key = encodeURIComponent(key) + '=';
|
||||
|
||||
if (queryString.indexOf(_key) > -1) {
|
||||
values = queryString
|
||||
.split(_key)
|
||||
.slice(1)
|
||||
.map(function(part) {
|
||||
return part.split('&')[0];
|
||||
})
|
||||
.map(decodeURIComponent)
|
||||
.map(function(string) {
|
||||
try {
|
||||
return JSON.parse(string);
|
||||
} catch(e) {}
|
||||
return string;
|
||||
});
|
||||
}
|
||||
|
||||
perfRunner.assert(values && values.length && values[0], 'expected ' + key + ' query param');
|
||||
return values;
|
||||
};
|
||||
|
||||
perfRunner.getQueryParamArrayOrDefault = function(key, defaultValue) {
|
||||
try {
|
||||
return perfRunner.getQueryParamArray(key);
|
||||
} catch (e) {}
|
||||
return defaultValue;
|
||||
};
|
||||
|
||||
perfRunner.Polyfill = function() {
|
||||
if (typeof Function.prototype.bind !== 'undefined') {
|
||||
return;
|
||||
}
|
||||
perfRunner.WriteScript({src:'/node_modules/es5-shim/es5-shim.js', cache:true});
|
||||
perfRunner.WriteScript({src:'/node_modules/es5-shim/es5-sham.js', cache:true});
|
||||
};
|
||||
|
||||
perfRunner.BenchmarkResults = function(props) {
|
||||
return perfRunner.roundNumberWithPrecision(props.stats.mean * 1000) + 'ms/op';
|
||||
};
|
||||
|
||||
perfRunner.roundNumberWithPrecision = function(number, precision) {
|
||||
if (!precision) {
|
||||
precision = 1000;
|
||||
}
|
||||
return Math.round(number * precision) / precision;
|
||||
};
|
||||
|
||||
perfRunner.quickBench = function(benchmarkOptions, onComplete, onBeforeStart) {
|
||||
var bench = new Benchmark(benchmarkOptions);
|
||||
if (onBeforeStart) {
|
||||
onBeforeStart(null, bench);
|
||||
}
|
||||
|
||||
bench.on('error', function(event) {
|
||||
console.error(event.message);
|
||||
console.log(event.target.compiled.toString());
|
||||
onComplete(Error(event.error));
|
||||
});
|
||||
|
||||
bench.on('start', function() {
|
||||
console.log('starting', bench.name);
|
||||
});
|
||||
|
||||
bench.on('cycle', function() {
|
||||
var benchmark = this,
|
||||
size = benchmark.stats.size;
|
||||
|
||||
if (!benchmark.aborted) {
|
||||
console.warn(benchmark.name + ' × ' + benchmark.count +
|
||||
' (' + benchmark.stats.sample.length + ' samples)' +
|
||||
' (' + Math.round(1 / benchmark.stats.mean) + ' ops/sec' + ')' +
|
||||
' (' + (benchmark.stats.mean * 1000) + ' ms/op' + ')' +
|
||||
' (±' + benchmark.stats.rme.toFixed(2) + '%)' +
|
||||
' with ' + React.version
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
bench.on('complete', function() {
|
||||
var results = {
|
||||
platform: Benchmark.platform.description,
|
||||
react: React.version,
|
||||
name: bench.name
|
||||
// times: bench.times,
|
||||
// stats: bench.stats
|
||||
};
|
||||
|
||||
results['s/op'] = bench.stats.mean;
|
||||
results['ms/op'] = results['s/op'] * 1000;
|
||||
results['op/s'] = 1 / results['s/op'];
|
||||
results['% frame 60'] = results['ms/op'] / (1000 / 60) * 100;
|
||||
|
||||
console.log(results);
|
||||
onComplete(null, results);
|
||||
});
|
||||
|
||||
bench.run();
|
||||
};
|
||||
|
||||
perfRunner.singleTest = function(benchmarkOptions, onComplete) {
|
||||
var bench = Benchmark(exports);
|
||||
bench.on('complete', function() {
|
||||
var results = {
|
||||
platform: Benchmark.platform.description,
|
||||
react: React.version,
|
||||
name: bench.name,
|
||||
stats: bench.stats
|
||||
};
|
||||
onComplete(results);
|
||||
});
|
||||
bench.run();
|
||||
};
|
||||
|
||||
perfRunner.ViewObject = function(props) {
|
||||
var value = props.value;
|
||||
delete props.value;
|
||||
|
||||
if (typeof value !== 'object') {
|
||||
return React.DOM.span(props, [JSON.stringify(value), ' ', typeof value]);
|
||||
}
|
||||
|
||||
return React.DOM.table(props, Object.keys(value).map(function(key) {
|
||||
return React.DOM.tr(null,
|
||||
React.DOM.th(null, key),
|
||||
React.DOM.td(null, perfRunner.ViewObject({key:key, value:value[key]}))
|
||||
);
|
||||
}));
|
||||
};
|
||||
@@ -1,145 +0,0 @@
|
||||
todolist = {};
|
||||
|
||||
todolist.ID = Date.now();
|
||||
|
||||
todolist.now = window.performance && window.performance.now && window.performance.now.bind(window.performance) || Date.now.bind(Date);
|
||||
|
||||
todolist.App = React.createClass({
|
||||
propTypes: {
|
||||
fakeDataCount: React.PropTypes.number
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
var todos;
|
||||
if (this.props.fakeDataCount) {
|
||||
todos = Array(this.props.fakeDataCount + 1).join(',').split(',').map(function(ignore, index) {
|
||||
return {
|
||||
id: index,
|
||||
title: 'Title ' + index + ' ' + Math.random().toString(36).substring(2, 16),
|
||||
completed: !!(index % 2)
|
||||
};
|
||||
});
|
||||
}
|
||||
return {
|
||||
timerStart: todolist.now(),
|
||||
timerEnd: null,
|
||||
timerEvent: 'getInitialState',
|
||||
todos: todos || this.props.initialData || []
|
||||
};
|
||||
},
|
||||
componentWillUpdate: function(props, state) {
|
||||
state.todos = state.todos.filter(function(todo) {
|
||||
return !todo.deleted;
|
||||
});
|
||||
},
|
||||
addItem: function(title, callback) {
|
||||
if (title == null || title === '') {
|
||||
var error = Error('invalid title');
|
||||
if (!callback) {
|
||||
throw error;
|
||||
}
|
||||
return callback(error);
|
||||
}
|
||||
var todos = this.state.todos.slice();
|
||||
var todo = {
|
||||
id: ++todolist.ID,
|
||||
title: title,
|
||||
completed: false
|
||||
};
|
||||
todos.push(todo);
|
||||
if (callback) {
|
||||
callback = callback.bind(this, todo);
|
||||
}
|
||||
this.setState({timerEvent:'addItem', timerStart:todolist.now(), timerEnd:null, todos:todos}, callback);
|
||||
return todo;
|
||||
},
|
||||
deleteItemById: function(id, callback) {
|
||||
var todo = this._getById(id);
|
||||
if (!todo) {
|
||||
return callback && callback(Error('todo with id ' + id + ' not found'));
|
||||
}
|
||||
todo.deleted = true;
|
||||
this.setState({timerEvent:'deleteItemById', timerStart:todolist.now(), timerEnd:null, todos:this.state.todos}, callback);
|
||||
},
|
||||
setItemCompleted: function(id, completed, callback) {
|
||||
var todo = this._getById(id);
|
||||
if (!todo) {
|
||||
return callback && callback(Error('todo with id ' + id + ' not found'));
|
||||
}
|
||||
todo.completed = completed;
|
||||
this.setState({timerEvent:'setItemCompleted', timerStart:todolist.now(), timerEnd:null, todos:this.state.todos}, callback);
|
||||
},
|
||||
_getById: function(id) {
|
||||
id = +id;
|
||||
var todos = this.state.todos;
|
||||
for (var index = todos.length; --index >= 0;) {
|
||||
if (todos[index].id === id) {
|
||||
return todos[index];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
_handleItemCompletedCheckboxChange: function(event) {
|
||||
var node = event.target;
|
||||
this.setItemCompleted(node.value, node.checked);
|
||||
},
|
||||
_handleItemDeletedButton: function(event) {
|
||||
var node = event.target;
|
||||
this.deleteItemById(node.value);
|
||||
},
|
||||
_renderTodoItem: function(todo, index) {
|
||||
return (
|
||||
React.DOM.li({key:todo.id},
|
||||
React.DOM.button({value:todo.id, onClick:this._handleItemDeletedButton}, 'x'),
|
||||
React.DOM.input({type:'checkbox', value:todo.id, checked:todo.completed, onChange:this._handleItemCompletedCheckboxChange}),
|
||||
' ',
|
||||
React.DOM.span({style:{'text-decoration':todo.completed ? 'line-through' : ''}}, todo.title)
|
||||
)
|
||||
);
|
||||
},
|
||||
render: function() {
|
||||
if (!this.state.timerEnd) {
|
||||
this.state.timerEnd = todolist.now();
|
||||
}
|
||||
if (this.props.onRender) {
|
||||
this.props.onRender();
|
||||
}
|
||||
return (
|
||||
React.DOM.div(null,
|
||||
React.DOM.h1(null, 'TODO'),
|
||||
React.DOM.h3(null, this.state.timerEvent, ' ', this.state.timerEnd - this.state.timerStart, 'ms'),
|
||||
todolist.NewItemForm({onEnter:this.addItem, autoFocus:true}),
|
||||
React.DOM.ol(null, this.state.todos.map(this._renderTodoItem))
|
||||
)
|
||||
);
|
||||
},
|
||||
componentDidMount: function(rootNode) {
|
||||
if (this.props.onDidMount) {
|
||||
this.props.onDidMount(rootNode);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
todolist.NewItemForm = React.createClass({
|
||||
_handleNewItemKeyDown: function(event) {
|
||||
if (event.which !== 13/*enter key*/) {
|
||||
return;
|
||||
}
|
||||
var node = this.refs.text.getDOMNode();
|
||||
var value = node.value;
|
||||
node.value = '';
|
||||
this.props.onEnter(value);
|
||||
return false;
|
||||
},
|
||||
render: function() {
|
||||
var props = {};
|
||||
for (var key in this.props) {
|
||||
if (key !== 'onEnter') {
|
||||
props[key] = this.props[key];
|
||||
}
|
||||
}
|
||||
props.ref = 'text';
|
||||
props.onKeyDown = this.props.onEnter && this._handleNewItemKeyDown;
|
||||
return React.DOM.input(props);
|
||||
}
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>todolist</title>
|
||||
|
||||
<script src="perf-test-runner.browser.js"></script>
|
||||
<script> perfRunner.Polyfill(); </script>
|
||||
<script src="../../build/react.min.js"></script>
|
||||
<script src="todolist.browser.js"></script>
|
||||
|
||||
<script>
|
||||
function main(){
|
||||
var app = todolist.App({ fakeDataCount:333 });
|
||||
React.render(app, document.body);
|
||||
}
|
||||
window.onload = main;
|
||||
</script>
|
||||
@@ -1,59 +0,0 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Perf Test Runner</title>
|
||||
|
||||
<script src="../node_modules/platform/platform.js"></script>
|
||||
<script src="../node_modules/benchmark/benchmark.js"></script>
|
||||
<script src="lib/perf-test-runner.browser.js"></script>
|
||||
|
||||
<script> perfRunner.Polyfill(); </script>
|
||||
|
||||
<script>
|
||||
|
||||
perfRunner.WriteReactLibScript({
|
||||
version: perfRunner.getQueryParamArrayOrDefault('react', [null])[0],
|
||||
debug: perfRunner.getQueryParamArrayOrDefault('debug', [false])[0]
|
||||
});
|
||||
|
||||
perfRunner.WriteScript({src:"lib/todolist.browser.js"});
|
||||
|
||||
perfRunner.WriteTestScript({ test:perfRunner.getQueryParamArray('test') });
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
|
||||
function checkIfReady(){
|
||||
if (!window.exports) return setTimeout(checkIfReady, 50);
|
||||
|
||||
console.timeStamp && console.timeStamp(perfRunner.getQueryParamArray('test'));
|
||||
if (typeof gc == 'function') gc();
|
||||
window.parent.postMessage(perfRunner.getQueryParamArrayOrDefault('callback', ['Ready!'])[0], '*');
|
||||
}
|
||||
checkIfReady();
|
||||
|
||||
function main(callback){
|
||||
perfRunner.singleTest(exports, function(results){
|
||||
document.getElementById('results').textContent = JSON.stringify(results, null, 2);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
function runOnce(callback){
|
||||
setTimeout(function(){
|
||||
exports.fn({resolve: function(){
|
||||
setTimeout(callback, 0);
|
||||
}});
|
||||
},0);
|
||||
}
|
||||
|
||||
</script>
|
||||
<button autofocus onclick="if (disabled) return false; main(function(){ disabled=false; textContent='Run again!'; }); textContent='Running!'; disabled=true">Run!</button>
|
||||
<div>
|
||||
<button onclick="exports.setup();">Setup!</button>
|
||||
<button onclick="if (disabled) return false; runOnce(function(){ disabled=false; textContent='Run again!'; }); textContent='Running!'; disabled=true">Run once!</button>
|
||||
<button onclick="exports.teardown();">Teardown!</button>
|
||||
</div>
|
||||
|
||||
<pre id=results style="font-size:9px"></pre>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
if (typeof exports === 'undefined') {
|
||||
exports = {};
|
||||
}
|
||||
|
||||
/*http://benchmarkjs.com/docs#options*/
|
||||
|
||||
exports.name = 'React.DOM.div, no props';
|
||||
|
||||
exports.fn = function() {
|
||||
React.DOM.div(null, 'lol, perf testing ', this.count);
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
if (typeof exports === 'undefined') {
|
||||
exports = {};
|
||||
}
|
||||
|
||||
/*http://benchmarkjs.com/docs#options*/
|
||||
|
||||
exports.name = 'unmountComponentAtNode';
|
||||
|
||||
exports.setup = function() {
|
||||
_rootNode = document.createElement('div');
|
||||
document.body.appendChild(_rootNode);
|
||||
var _firstChild = React.DOM.div(null, 'lol, perf testing ', this.count);
|
||||
React.render(_firstChild, _rootNode);
|
||||
};
|
||||
exports.fn = function() {
|
||||
if (React.unmountAndReleaseReactRootNode) {
|
||||
React.unmountAndReleaseReactRootNode(_rootNode);
|
||||
} else {
|
||||
React.unmountComponentAtNode(_rootNode);
|
||||
}
|
||||
};
|
||||
@@ -1,91 +0,0 @@
|
||||
if (typeof exports === 'undefined') {
|
||||
exports = {};
|
||||
}
|
||||
|
||||
/*http://benchmarkjs.com/docs#options*/
|
||||
|
||||
exports.name = 'propTypes';
|
||||
|
||||
var Thing = function() {};
|
||||
var List;
|
||||
var ListItem;
|
||||
var MyReactComponent;
|
||||
var _rootNode;
|
||||
|
||||
function func() {
|
||||
return 'this is a function';
|
||||
}
|
||||
|
||||
exports.setup = function() {
|
||||
List = React.createClass({
|
||||
propTypes: {
|
||||
array: React.PropTypes.array,
|
||||
bool: React.PropTypes.bool.isRequired,
|
||||
number: React.PropTypes.number,
|
||||
string: React.PropTypes.string.isRequired,
|
||||
func: React.PropTypes.func.isRequired,
|
||||
node: React.PropTypes.node.isRequired,
|
||||
instanceOf: React.PropTypes.instanceOf(Thing).isRequired
|
||||
},
|
||||
render: function() {
|
||||
return React.DOM.ul(null, this.props.children);
|
||||
}
|
||||
});
|
||||
|
||||
ListItem = React.createClass({
|
||||
propTypes: {
|
||||
array: React.PropTypes.array,
|
||||
bool: React.PropTypes.bool.isRequired,
|
||||
number: React.PropTypes.number,
|
||||
string: React.PropTypes.string.isRequired,
|
||||
func: React.PropTypes.func.isRequired,
|
||||
node: React.PropTypes.node.isRequired,
|
||||
node2: React.PropTypes.node.isRequired,
|
||||
instanceOf: React.PropTypes.instanceOf(Thing).isRequired,
|
||||
element: React.PropTypes.element.isRequired
|
||||
},
|
||||
render: function() {
|
||||
return React.DOM.li(null,
|
||||
this.props.number + this.props.string + this.props.node
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
MyReactComponent = React.createClass({
|
||||
render: function() {
|
||||
return React.DOM.span();
|
||||
}
|
||||
});
|
||||
|
||||
_rootNode = document.createElement('div');
|
||||
document.body.appendChild(_rootNode);
|
||||
};
|
||||
exports.fn = function() {
|
||||
var items = [];
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
items.push(ListItem({
|
||||
array: [11, 12, 13, 14, 15, 16, 17, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
||||
bool: false,
|
||||
number: Math.random(),
|
||||
string: 'banana banana banana',
|
||||
func: func,
|
||||
node: 'renderable string',
|
||||
node2: [MyReactComponent(), 'a string'],
|
||||
instanceOf: new Thing(),
|
||||
element: MyReactComponent()
|
||||
}));
|
||||
}
|
||||
|
||||
React.render(List({
|
||||
array: [11, 12, 13, 14, 15, 16, 17, 18, 19, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
||||
bool: false,
|
||||
number: Math.random(),
|
||||
string: 'banana banana banana',
|
||||
func: func,
|
||||
renderable: 'renderable string',
|
||||
instanceOf: new Thing()
|
||||
}, items), _rootNode);
|
||||
};
|
||||
exports.teardown = function() {
|
||||
React.unmountComponentAtNode(_rootNode);
|
||||
};
|
||||
@@ -1,22 +0,0 @@
|
||||
if (typeof exports === 'undefined') {
|
||||
exports = {};
|
||||
}
|
||||
|
||||
/*http://benchmarkjs.com/docs#options*/
|
||||
|
||||
exports.name = 'React.render single div';
|
||||
|
||||
exports.setup = function() {
|
||||
_rootNode = document.createElement('div');
|
||||
document.body.appendChild(_rootNode);
|
||||
};
|
||||
exports.fn = function() {
|
||||
React.render(React.DOM.div(null, 'lol, perf testing ', this.count), _rootNode);
|
||||
};
|
||||
exports.teardown = function() {
|
||||
if (React.unmountAndReleaseReactRootNode) {
|
||||
React.unmountAndReleaseReactRootNode(_rootNode);
|
||||
} else {
|
||||
React.unmountComponentAtNode(_rootNode);
|
||||
}
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
if (typeof exports === 'undefined') {
|
||||
exports = {};
|
||||
}
|
||||
|
||||
/*http://benchmarkjs.com/docs#options*/
|
||||
|
||||
exports.name = 'Trivial benchmark to verify that everything works';
|
||||
|
||||
exports.setup = function() {
|
||||
var foo;
|
||||
};
|
||||
exports.fn = function() {
|
||||
foo = Array(999).join('Howdy!\n');
|
||||
};
|
||||
exports.teardown = function() {
|
||||
foo = null;
|
||||
};
|
||||
@@ -1,45 +0,0 @@
|
||||
if (typeof exports === 'undefined') {
|
||||
exports = {};
|
||||
}
|
||||
|
||||
/*http://benchmarkjs.com/docs#options*/
|
||||
|
||||
exports.name = 'From setState to callback (x5)';
|
||||
|
||||
exports.defer = true;
|
||||
|
||||
exports.setup = function() {
|
||||
_rootNode = document.createElement('div');
|
||||
document.body.appendChild(_rootNode);
|
||||
setState = null;
|
||||
|
||||
var AwesomeComponent = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {random:null};
|
||||
},
|
||||
render: function() {
|
||||
if (!setState) {
|
||||
setState = this.setState.bind(this);
|
||||
}
|
||||
return React.DOM.div(null, this.state.random);
|
||||
}
|
||||
});
|
||||
|
||||
React.render(AwesomeComponent(null), _rootNode);
|
||||
};
|
||||
exports.fn = function(deferred) {
|
||||
setState({random: Date.now() + Math.random()}, function() {
|
||||
setState({random: Date.now() + Math.random()}, function() {
|
||||
setState({random: Date.now() + Math.random()}, function() {
|
||||
setState({random: Date.now() + Math.random()}, function() {
|
||||
setState({random: Date.now() + Math.random()}, function() {
|
||||
deferred.resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
exports.teardown = function() {
|
||||
React.unmountComponentAtNode(_rootNode);
|
||||
};
|
||||
@@ -1,37 +0,0 @@
|
||||
if (typeof exports === 'undefined') {
|
||||
exports = {};
|
||||
}
|
||||
|
||||
/*http://benchmarkjs.com/docs#options*/
|
||||
|
||||
exports.name = 'From setState to callback';
|
||||
|
||||
exports.defer = true;
|
||||
|
||||
exports.setup = function() {
|
||||
_rootNode = document.createElement('div');
|
||||
document.body.appendChild(_rootNode);
|
||||
setState = null;
|
||||
|
||||
var AwesomeComponent = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {random:null};
|
||||
},
|
||||
render: function() {
|
||||
if (!setState) {
|
||||
setState = this.setState.bind(this);
|
||||
}
|
||||
return React.DOM.div(null, this.state.random);
|
||||
}
|
||||
});
|
||||
|
||||
React.render(AwesomeComponent(null), _rootNode);
|
||||
};
|
||||
exports.fn = function(deferred) {
|
||||
setState({random: Date.now() + Math.random()}, function() {
|
||||
deferred.resolve();
|
||||
});
|
||||
};
|
||||
exports.teardown = function() {
|
||||
React.unmountComponentAtNode(_rootNode);
|
||||
};
|
||||
@@ -1,27 +0,0 @@
|
||||
if (typeof exports === 'undefined') {
|
||||
exports = {};
|
||||
}
|
||||
|
||||
/*http://benchmarkjs.com/docs#options*/
|
||||
|
||||
exports.name = 'shouldComponentUpdate';
|
||||
|
||||
exports.setup = function() {
|
||||
var AwesomeComponent = React.createClass({
|
||||
shouldComponentUpdate: function() {
|
||||
return false;
|
||||
},
|
||||
render: function() {
|
||||
return React.DOM.div({});
|
||||
}
|
||||
});
|
||||
|
||||
var _rootNode = document.createElement('div');
|
||||
document.body.appendChild(_rootNode);
|
||||
};
|
||||
exports.fn = function() {
|
||||
React.render(AwesomeComponent(null), _rootNode);
|
||||
};
|
||||
exports.teardown = function() {
|
||||
React.unmountComponentAtNode(_rootNode);
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
if (typeof exports === 'undefined') {
|
||||
exports = {};
|
||||
}
|
||||
|
||||
/*http://benchmarkjs.com/docs#options*/
|
||||
|
||||
exports.name = 'todolist from addItem to callback';
|
||||
|
||||
exports.defer = true;
|
||||
|
||||
exports.setup = function() {
|
||||
_rootNode = document.createElement('div');
|
||||
document.body.appendChild(_rootNode);
|
||||
var appDescriptor = todolist.App({fakeDataCount: 333});
|
||||
_app = React.render(appDescriptor, _rootNode);
|
||||
};
|
||||
exports.fn = function(deferred) {
|
||||
var liCount = document.getElementsByTagName('li').length;
|
||||
_app.addItem(Math.random(), function() {
|
||||
if (document.getElementsByTagName('li').length <= liCount) {
|
||||
throw Error('expected a list item to be added to the dom');
|
||||
}
|
||||
deferred.resolve();
|
||||
});
|
||||
};
|
||||
exports.teardown = function() {
|
||||
React.unmountComponentAtNode(_rootNode);
|
||||
_rootNode.parentNode.removeChild(_rootNode);
|
||||
_rootNode = null;
|
||||
_app = null;
|
||||
};
|
||||
@@ -1,58 +0,0 @@
|
||||
if (typeof exports === 'undefined') {
|
||||
exports = {};
|
||||
}
|
||||
|
||||
/*http://benchmarkjs.com/docs#options*/
|
||||
|
||||
_timesToRun = 2;
|
||||
|
||||
exports.name = 'todolist add, complete, remove (x' + _timesToRun + ')';
|
||||
|
||||
exports.defer = true;
|
||||
|
||||
exports.setup = function() {
|
||||
_rootNode = document.createElement('div');
|
||||
document.body.appendChild(_rootNode);
|
||||
var appDescriptor = todolist.App({fakeDataCount: 333});
|
||||
_app = React.render(appDescriptor, _rootNode);
|
||||
};
|
||||
|
||||
exports.fn = function(deferred) {
|
||||
var originalLiCount = document.getElementsByTagName('li').length;
|
||||
|
||||
var todos = [];
|
||||
var times = _timesToRun;
|
||||
while (times-- >= 0) {
|
||||
todos.push(_app.addItem(times + 1));
|
||||
}
|
||||
|
||||
todos.forEach(function(todo) {
|
||||
_app.setItemCompleted(todo.id);
|
||||
});
|
||||
|
||||
todos.forEach(function(todo) {
|
||||
_app.deleteItemById(todo.id);
|
||||
});
|
||||
|
||||
todos = null;
|
||||
|
||||
_app.addItem(Math.random(), function(todo) {
|
||||
if (document.getElementsByTagName('li').length <= originalLiCount) {
|
||||
throw Error('expected a list item to be added to the dom');
|
||||
}
|
||||
|
||||
_app.deleteItemById(todo.id, function() {
|
||||
if (document.getElementsByTagName('li').length !== originalLiCount) {
|
||||
throw Error('expected everything to be done by now');
|
||||
}
|
||||
deferred.resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
exports.teardown = function() {
|
||||
React.unmountComponentAtNode(_rootNode);
|
||||
_rootNode.parentNode.removeChild(_rootNode);
|
||||
_rootNode = null;
|
||||
_app = null;
|
||||
};
|
||||
@@ -1,34 +0,0 @@
|
||||
if (typeof exports === 'undefined') {
|
||||
exports = {};
|
||||
}
|
||||
|
||||
/*http://benchmarkjs.com/docs#options*/
|
||||
|
||||
exports.name = 'todolist setItemCompleted';
|
||||
|
||||
exports.defer = true;
|
||||
|
||||
exports.setup = function() {
|
||||
_rootNode = document.createElement('div');
|
||||
document.body.appendChild(_rootNode);
|
||||
var appDescriptor = todolist.App({fakeDataCount: 333});
|
||||
_app = React.render(appDescriptor, _rootNode);
|
||||
_todo1 = _app.addItem('Howdy 1!');
|
||||
_todo2 = _app.addItem('Howdy 2!');
|
||||
_todo3 = _app.addItem('Howdy 3!');
|
||||
};
|
||||
|
||||
exports.fn = function(deferred) {
|
||||
_app.setItemCompleted(_todo1.id, !_todo1.completed);
|
||||
_app.setItemCompleted(_todo2.id, !_todo2.completed);
|
||||
_app.setItemCompleted(_todo3.id, !_todo3.completed, function() {
|
||||
deferred.resolve();
|
||||
});
|
||||
};
|
||||
|
||||
exports.teardown = function() {
|
||||
React.unmountComponentAtNode(_rootNode);
|
||||
_rootNode.parentNode.removeChild(_rootNode);
|
||||
_rootNode = null;
|
||||
_app = null;
|
||||
};
|
||||
@@ -1,30 +0,0 @@
|
||||
if (typeof exports === 'undefined') {
|
||||
exports = {};
|
||||
}
|
||||
|
||||
/*http://benchmarkjs.com/docs#options*/
|
||||
|
||||
exports.name =
|
||||
'todolist from renderComponent to renderComponent callback (333 rows)';
|
||||
|
||||
exports.defer = true;
|
||||
|
||||
exports.setup = function() {
|
||||
if (typeof _rootNode !== 'undefined') {
|
||||
throw Error('should teardown before running setup again');
|
||||
}
|
||||
_rootNode = document.createElement('div');
|
||||
document.body.appendChild(_rootNode);
|
||||
};
|
||||
|
||||
exports.fn = function(deferred) {
|
||||
React.render(todolist.App({fakeDataCount: 333}), _rootNode, function() {
|
||||
deferred.resolve();
|
||||
});
|
||||
};
|
||||
|
||||
exports.teardown = function() {
|
||||
React.unmountComponentAtNode(_rootNode);
|
||||
_rootNode.parentNode.removeChild(_rootNode);
|
||||
_rootNode = undefined;
|
||||
};
|
||||
Reference in New Issue
Block a user