Merge pull request #5550 from spicyj/cc-speed

Make createClass 10-15% faster on complex specs
This commit is contained in:
Ben Alpert
2015-12-14 14:45:44 -08:00
2 changed files with 259 additions and 17 deletions
+16 -17
View File
@@ -402,7 +402,7 @@ function validateTypeDef(Constructor, typeDef, location) {
}
}
function validateMethodOverride(proto, name) {
function validateMethodOverride(isAlreadyDefined, name) {
var specPolicy = ReactClassInterface.hasOwnProperty(name) ?
ReactClassInterface[name] :
null;
@@ -419,7 +419,7 @@ function validateMethodOverride(proto, name) {
}
// Disallow defining methods more than once unless explicitly allowed.
if (proto.hasOwnProperty(name)) {
if (isAlreadyDefined) {
invariant(
specPolicy === SpecPolicy.DEFINE_MANY ||
specPolicy === SpecPolicy.DEFINE_MANY_MERGED,
@@ -453,6 +453,7 @@ function mixSpecIntoComponent(Constructor, spec) {
);
var proto = Constructor.prototype;
var autoBindPairs = proto.__reactAutoBindPairs;
// By handling mixins before any other properties, we ensure the same
// chaining order is applied to methods with DEFINE_MANY policy, whether
@@ -472,7 +473,8 @@ function mixSpecIntoComponent(Constructor, spec) {
}
var property = spec[name];
validateMethodOverride(proto, name);
var isAlreadyDefined = proto.hasOwnProperty(name);
validateMethodOverride(isAlreadyDefined, name);
if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
RESERVED_SPEC_KEYS[name](Constructor, property);
@@ -483,7 +485,6 @@ function mixSpecIntoComponent(Constructor, spec) {
// 2. Overridden methods (that were mixed in).
var isReactClassMethod =
ReactClassInterface.hasOwnProperty(name);
var isAlreadyDefined = proto.hasOwnProperty(name);
var isFunction = typeof property === 'function';
var shouldAutoBind =
isFunction &&
@@ -492,10 +493,7 @@ function mixSpecIntoComponent(Constructor, spec) {
spec.autobind !== false;
if (shouldAutoBind) {
if (!proto.__reactAutoBindMap) {
proto.__reactAutoBindMap = {};
}
proto.__reactAutoBindMap[name] = property;
autoBindPairs.push(name, property);
proto[name] = property;
} else {
if (isAlreadyDefined) {
@@ -688,14 +686,14 @@ function bindAutoBindMethod(component, method) {
* @param {object} component Component whose method is going to be bound.
*/
function bindAutoBindMethods(component) {
for (var autoBindKey in component.__reactAutoBindMap) {
if (component.__reactAutoBindMap.hasOwnProperty(autoBindKey)) {
var method = component.__reactAutoBindMap[autoBindKey];
component[autoBindKey] = bindAutoBindMethod(
component,
method
);
}
var pairs = component.__reactAutoBindPairs;
for (var i = 0; i < pairs.length; i += 2) {
var autoBindKey = pairs[i];
var method = pairs[i + 1];
component[autoBindKey] = bindAutoBindMethod(
component,
method
);
}
}
@@ -762,7 +760,7 @@ var ReactClass = {
}
// Wire up auto-binding
if (this.__reactAutoBindMap) {
if (this.__reactAutoBindPairs.length) {
bindAutoBindMethods(this);
}
@@ -796,6 +794,7 @@ var ReactClass = {
};
Constructor.prototype = new ReactClassComponent();
Constructor.prototype.constructor = Constructor;
Constructor.prototype.__reactAutoBindPairs = [];
injectedMixins.forEach(
mixSpecIntoComponent.bind(null, Constructor)