mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
206 lines
5.8 KiB
JavaScript
206 lines
5.8 KiB
JavaScript
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)
|
|
);
|
|
}
|
|
|
|
});
|