mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 00:20:04 +01:00
Add a simple initial-render benchmark test case
This commit is contained in:
parent
65b9ceb4f8
commit
e849819cb6
|
|
@ -11,4 +11,5 @@ docs/vendor/bundle/
|
|||
examples/
|
||||
# Ignore built files.
|
||||
build/
|
||||
scripts/bench/bench-*.js
|
||||
vendor/react-dom.js
|
||||
|
|
|
|||
23
scripts/bench/README.md
Normal file
23
scripts/bench/README.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
Work-in-progress benchmarks.
|
||||
|
||||
## Running one
|
||||
One thing you can do with them is benchmark initial render time for a realistic hierarchy:
|
||||
|
||||
```
|
||||
$ which jsc
|
||||
/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Resources/jsc
|
||||
$ jsc react-0.14.0.min.js bench-pe-es5.js -e 'var START=Date.now(); React.renderToString(React.createElement(Benchmark)); var END=Date.now(); print(END-START);'
|
||||
45
|
||||
```
|
||||
|
||||
Substitute `js` or `v8` for `jsc` to use SpiderMonkey or V8, respectively, if you've installed them.
|
||||
|
||||
## Creating one
|
||||
|
||||
To create one, copy `extract-component.js` to your clipboard and paste it into the Chrome console on facebook.com, perhaps after changing the root ID if you don't want the tree with ID `.0`.
|
||||
|
||||
Then to convert it to ES5:
|
||||
|
||||
```
|
||||
babel --whitelist react,react.displayName --compact false bench-pe.js >bench-pe-es5.js
|
||||
```
|
||||
9011
scripts/bench/bench-pe-es5.js
Normal file
9011
scripts/bench/bench-pe-es5.js
Normal file
File diff suppressed because it is too large
Load Diff
6681
scripts/bench/bench-pe.js
Normal file
6681
scripts/bench/bench-pe.js
Normal file
File diff suppressed because it is too large
Load Diff
169
scripts/bench/extract-component.js
Normal file
169
scripts/bench/extract-component.js
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/*global copy */
|
||||
/*eslint-disable no-debugger */
|
||||
|
||||
// Copy and paste this file into your (Chrome) browser console after changing
|
||||
// the React root ID. Works on facebook.com as of 10/28/15 (use a test user).
|
||||
|
||||
'use strict';
|
||||
|
||||
var rootID = '.0';
|
||||
|
||||
var React = require('React');
|
||||
var ReactMount = require('ReactMount');
|
||||
copy(print(ReactMount._instancesByReactRootID[rootID]._renderedComponent));
|
||||
|
||||
function elementMeta(element) {
|
||||
var meta = '';
|
||||
var key = element.key;
|
||||
if (key) {
|
||||
meta += ' key={' + JSON.stringify(key) + '}';
|
||||
}
|
||||
var ref = element.ref;
|
||||
if (typeof ref === 'string') {
|
||||
meta += ' ref={' + JSON.stringify(ref) + '}';
|
||||
} else if (typeof ref === 'function') {
|
||||
meta += ' ref={function() {}}';
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
|
||||
function print(outerComponent) {
|
||||
function addComposite(name, child) {
|
||||
output += 'var ' + name + ' = React.createClass({\n';
|
||||
output += ' render: function() {\n';
|
||||
if (child.indexOf('\n') !== -1) {
|
||||
output += ' return (\n';
|
||||
output += child.replace(/^|\n/g, '$& ') + '\n';
|
||||
output += ' );\n';
|
||||
} else {
|
||||
output += ' return ' + child + ';\n';
|
||||
}
|
||||
output += ' },\n';
|
||||
output += '});\n';
|
||||
output += '\n';
|
||||
}
|
||||
|
||||
function printImpl(component) {
|
||||
var element = component._currentElement;
|
||||
|
||||
// Empty component
|
||||
if (element === null || element === false) {
|
||||
return '' + element;
|
||||
}
|
||||
|
||||
// Text component
|
||||
if (typeof element === 'string' || typeof element === 'number') {
|
||||
return JSON.stringify(element);
|
||||
}
|
||||
|
||||
// Composite component
|
||||
if (typeof element.type === 'function') {
|
||||
var rendered = printImpl(component._renderedComponent);
|
||||
var name = (component.getName() || 'Component').replace(/(?:^[^a-z]|\W)+/gi, '_') + counter++;
|
||||
if (!/^[A-Z]/.test(name)) {
|
||||
name = '_' + name;
|
||||
}
|
||||
addComposite(name, rendered);
|
||||
var compositeMarkup = '<' + name;
|
||||
compositeMarkup += elementMeta(component._currentElement);
|
||||
compositeMarkup += ' />';
|
||||
return compositeMarkup;
|
||||
}
|
||||
|
||||
// Native component
|
||||
if (typeof element.type === 'string') {
|
||||
var markup = '<' + element.type;
|
||||
markup += elementMeta(component._currentElement);
|
||||
for (var propKey in element.props) {
|
||||
var value = element.props[propKey];
|
||||
var valueString = null;
|
||||
if (propKey === 'style' || propKey === 'dangerouslySetInnerHTML') {
|
||||
valueString = JSON.stringify(value);
|
||||
} else if (propKey === 'children') {
|
||||
} else {
|
||||
if (typeof value === 'function') {
|
||||
valueString = 'function() {}';
|
||||
} else if (typeof value === 'string' || typeof value === 'number') {
|
||||
valueString = JSON.stringify(value);
|
||||
} else if (value == null || typeof value === 'boolean') {
|
||||
valueString = '' + value;
|
||||
} else if (typeof value === 'object') {
|
||||
valueString = '{}';
|
||||
console.log('smooshing', element.type, propKey, value);
|
||||
} else {
|
||||
debugger;
|
||||
throw new Error('huh? ' + typeof value + ' ' + value);
|
||||
}
|
||||
}
|
||||
if (valueString) {
|
||||
markup += ' ' + propKey + '={' + valueString + '}';
|
||||
}
|
||||
}
|
||||
markup += '>';
|
||||
|
||||
if (
|
||||
typeof element.props.children === 'string' ||
|
||||
typeof element.props.children === 'number'
|
||||
) {
|
||||
markup += '{' + JSON.stringify(element.props.children) + '}';
|
||||
} else if (component._renderedChildren) {
|
||||
var renderedChildren = component._renderedChildren;
|
||||
var keys = Object.keys(renderedChildren);
|
||||
var values = keys.map((childKey) => renderedChildren[childKey]);
|
||||
|
||||
if (keys.length) {
|
||||
function dump(children) {
|
||||
if (typeof children === 'boolean' || children == null) {
|
||||
return '' + children;
|
||||
}
|
||||
if (Array.isArray(children)) {
|
||||
return children.length ? (
|
||||
'[\n' +
|
||||
children.map(function(ch) {
|
||||
return ' ' + dump(ch).replace(/\n/g, '$& ') + ',\n';
|
||||
}).join('') +
|
||||
']'
|
||||
) : '[]';
|
||||
} else if (React.isValidElement(children) || typeof children === 'string' || typeof children === 'number') {
|
||||
return printImpl(values.shift());
|
||||
} else {
|
||||
debugger;
|
||||
throw new Error('hmm');
|
||||
}
|
||||
}
|
||||
|
||||
markup += '\n';
|
||||
var children = element.props.children;
|
||||
children = Array.isArray(children) ? children : [children];
|
||||
children.forEach(function(child) {
|
||||
var dumped = dump(child).replace(/\n/g, '$& ');
|
||||
if (dumped.charAt(0) === '<') {
|
||||
markup += ' ' + dumped + '\n';
|
||||
} else {
|
||||
markup += ' {' + dumped + '}\n';
|
||||
}
|
||||
});
|
||||
if (values.length !== 0) {
|
||||
debugger;
|
||||
throw new Error('not all children processed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
markup += '</' + element.type + '>';
|
||||
return markup;
|
||||
}
|
||||
|
||||
debugger;
|
||||
throw new Error('hmm');
|
||||
}
|
||||
|
||||
var output = '(function() {\n\n';
|
||||
var counter = 0;
|
||||
|
||||
var tail = printImpl(outerComponent);
|
||||
addComposite('Benchmark', tail);
|
||||
output += 'this.Benchmark = Benchmark;\n';
|
||||
output += '\n})(this);\n';
|
||||
return output;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user