React inlining: Refactor to reduce parsing cost
- Have the `jsx` helper do the `defaultProps` work instead of calling `defaultProps` inline. - Put `key` after `props` and make it optional. - Inline `children` as rest args instead of in the object. - Rename `createRawReactElement` to `jsx`. I wish I was kidding. Most of these are silly microoptimizations. In my test file (based off an internal RN app), this reduces the parsing overhead of inlining from around 1% to 0.1% in JSC and from 0.6% to 0.0% in V8 (compared to element inlining before this commit). Once parsed, the initial render with inlining is the same speed as not inlining in JSC and ~1% slower in V8. A second initial render in the same context (reusing the function objects, JIT, etc) is 2.0% faster in JSC and 5.5% faster in V8.
This commit is contained in:
@@ -29,14 +29,12 @@ export default function ({ types: t }) {
|
||||
if (hasRefOrSpread(open.attributes)) return;
|
||||
|
||||
// init
|
||||
let isComponent = true;
|
||||
let props = t.objectExpression([]);
|
||||
let key = t.nullLiteral();
|
||||
let key = null;
|
||||
let type = open.name;
|
||||
|
||||
if (t.isJSXIdentifier(type) && t.react.isCompatTag(type.name)) {
|
||||
type = t.stringLiteral(type.name);
|
||||
isComponent = false;
|
||||
}
|
||||
|
||||
function pushProp(objProps, key, value) {
|
||||
@@ -54,24 +52,16 @@ export default function ({ types: t }) {
|
||||
}
|
||||
}
|
||||
|
||||
if (node.children.length) {
|
||||
let args = [type, props];
|
||||
if (key || node.children.length) {
|
||||
let children = t.react.buildChildren(node);
|
||||
if (children.length) {
|
||||
children = children.length === 1 ? children[0] : t.arrayExpression(children);
|
||||
pushProp(props.properties, t.identifier("children"), children);
|
||||
}
|
||||
args.push(
|
||||
key || t.unaryExpression("void", t.numericLiteral(0), true),
|
||||
...children
|
||||
);
|
||||
}
|
||||
|
||||
if (isComponent) {
|
||||
let defProps = t.memberExpression(type, t.identifier("defaultProps"));
|
||||
if (props.properties.length) {
|
||||
props = t.callExpression(file.addHelper("defaultProps"), [defProps, props]);
|
||||
} else {
|
||||
props = t.logicalExpression("||", defProps, props);
|
||||
}
|
||||
}
|
||||
|
||||
let el = t.callExpression(file.addHelper("createRawReactElement"), [type, key, props]);
|
||||
let el = t.callExpression(file.addHelper("jsx"), args);
|
||||
path.replaceWith(el);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user