Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Refactor] improve performance for detecting class components #3267

Merged
merged 1 commit into from Apr 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -21,7 +21,9 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
* [Refactor] fix linter errors ([#3261][] @golopot)
* [Docs] [`no-unused-prop-types`]: fix syntax errors ([#3259][] @mrdulin)
* [Refactor] improve performance for detecting function components ([#3265][] @golopot)
* [Refactor] improve performance for detecting class components ([#3267][] @golopot)

[#3267]: https://github.com/yannickcr/eslint-plugin-react/pull/3267
[#3266]: https://github.com/yannickcr/eslint-plugin-react/pull/3266
[#3265]: https://github.com/yannickcr/eslint-plugin-react/pull/3265
[#3261]: https://github.com/yannickcr/eslint-plugin-react/pull/3261
Expand Down
26 changes: 21 additions & 5 deletions lib/util/Components.js
Expand Up @@ -259,20 +259,29 @@ function componentRule(rule, context) {
const utils = {

/**
* Check if the node is a React ES5 component
* Check if an ObjectExpression is a React ES5 component
*
* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if the node is a React ES5 component, false if not
*/
isES5Component(node) {
if (!node.parent) {
if (!node.parent || !node.parent.callee) {
return false;
}
return new RegExp(`^(${pragma}\\.)?${createClass}$`).test(sourceCode.getText(node.parent.callee));
const callee = node.parent.callee;
// React.createClass({})
if (callee.type === 'MemberExpression') {
return callee.object.name === pragma && callee.property.name === createClass;
}
// createClass({})
if (callee.type === 'Identifier') {
return callee.name === createClass;
}
return false;
},

/**
* Check if the node is a React ES6 component
* Check if a class is a React ES6 component
*
* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if the node is a React ES6 component, false if not
Expand All @@ -285,7 +294,14 @@ function componentRule(rule, context) {
if (!node.superClass) {
return false;
}
return new RegExp(`^(${pragma}\\.)?(Pure)?Component$`).test(sourceCode.getText(node.superClass));
if (node.superClass.type === 'MemberExpression') {
return node.superClass.object.name === pragma
&& /^(Pure)?Component$/.test(node.superClass.property.name);
}
if (node.superClass.type === 'Identifier') {
return /^(Pure)?Component$/.test(node.superClass.name);
Comment on lines +299 to +302
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a speed improvement from caching this non-global regex at module level?

Copy link
Contributor Author

@golopot golopot Apr 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried and didn't see a speed improvement. I suppose the compiler can compile the regexp once and reuse it afterwards.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This contrasts with the previous line RegExp(^(${pragma}\.)?(Pure)?Component$) where v8 have to compile the regexp at runtime at every function call.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we'll land it as-is then for now

}
return false;
},

/**
Expand Down