Merge pull request #4605 from appsmithorg/perf/ui/optimize-editableText-component

[Perf] Patch for bluperint to optimize editable text component
This commit is contained in:
Satish Gandham 2021-06-07 20:11:54 +05:30 committed by GitHub
commit 7c0f46a189
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 140 additions and 44 deletions

View File

@ -163,7 +163,8 @@
"test:unit": "$(npm bin)/jest -b --colors --no-cache --coverage --collectCoverage=true --coverageDirectory='../../' --coverageReporters='json-summary'",
"test:jest": "$(npm bin)/jest --watch",
"storybook": "start-storybook -p 9009 -s public",
"build-storybook": "build-storybook -s public"
"build-storybook": "build-storybook -s public",
"postinstall": "patch-package"
},
"resolution": {
"jest": "24.8.0"
@ -236,6 +237,8 @@
"mochawesome": "^5.0.0",
"mochawesome-report-generator": "^4.1.0",
"msw": "^0.28.0",
"patch-package": "^6.4.7",
"postinstall-postinstall": "^2.1.0",
"raw-loader": "^4.0.2",
"react-docgen-typescript-loader": "^3.6.0",
"react-is": "^16.12.0",

View File

@ -0,0 +1,22 @@
diff --git a/node_modules/@blueprintjs/core/lib/esm/components/editable-text/editableText.js b/node_modules/@blueprintjs/core/lib/esm/components/editable-text/editableText.js
index 84f03fa..5e5488a 100644
--- a/node_modules/@blueprintjs/core/lib/esm/components/editable-text/editableText.js
+++ b/node_modules/@blueprintjs/core/lib/esm/components/editable-text/editableText.js
@@ -188,7 +188,16 @@ var EditableText = /** @class */ (function (_super) {
if (this.state.isEditing && !prevState.isEditing) {
(_b = (_a = this.props).onEdit) === null || _b === void 0 ? void 0 : _b.call(_a, this.state.value);
}
- this.updateInputDimensions();
+ // updateInputDimensions is an expensive method. Call it only when the props
+ // it depends on change
+ if (this.state.value !== prevState.value ||
+ this.props.alwaysRenderInput !== prevProps.alwaysRenderInput ||
+ this.props.maxLines !== prevProps.maxLines ||
+ this.props.minLines !== prevProps.minLines ||
+ this.props.minWidth !== prevProps.minWidth ||
+ this.props.multiline !== prevProps.multiline) {
+ this.updateInputDimensions();
+ }
};
EditableText.prototype.renderInput = function (value) {
var _a = this.props, disabled = _a.disabled, maxLength = _a.maxLength, multiline = _a.multiline, type = _a.type, placeholder = _a.placeholder;

View File

@ -92,10 +92,25 @@ const TextContainer = styled.div<{ isValid: boolean; minimal: boolean }>`
`;
export function EditableText(props: EditableTextProps) {
const [isEditing, setIsEditing] = useState(!!props.isEditingDefault);
const [value, setStateValue] = useState(props.defaultValue);
const {
beforeUnmount,
className,
defaultValue,
editInteractionKind,
forceDefault,
hideEditIcon,
isEditingDefault,
isInvalid,
minimal,
onBlur,
onTextChanged,
placeholder,
updating,
valueTransform,
} = props;
const [isEditing, setIsEditing] = useState(!!isEditingDefault);
const [value, setStateValue] = useState(defaultValue);
const inputValRef = useRef("");
const { beforeUnmount } = props;
const setValue = useCallback((value) => {
inputValRef.current = value;
@ -103,16 +118,16 @@ export function EditableText(props: EditableTextProps) {
}, []);
useEffect(() => {
setValue(props.defaultValue);
}, [props.defaultValue]);
setValue(defaultValue);
}, [defaultValue]);
useEffect(() => {
setIsEditing(!!props.isEditingDefault);
}, [props.defaultValue, props.isEditingDefault]);
setIsEditing(!!isEditingDefault);
}, [defaultValue, isEditingDefault]);
useEffect(() => {
if (props.forceDefault === true) setValue(props.defaultValue);
}, [props.forceDefault, props.defaultValue]);
if (forceDefault === true) setValue(defaultValue);
}, [forceDefault, defaultValue]);
// at times onTextChange is not fired
// for example when the modal is closed on clicking the overlay
@ -128,58 +143,63 @@ export function EditableText(props: EditableTextProps) {
e.preventDefault();
e.stopPropagation();
};
const onChange = (_value: string) => {
props.onBlur && props.onBlur();
const isInvalid = props.isInvalid ? props.isInvalid(_value) : false;
if (!isInvalid) {
props.onTextChanged(_value);
setIsEditing(false);
} else {
Toaster.show({
text: "Invalid name",
variant: Variant.danger,
});
}
};
const onChange = useCallback(
(_value: string) => {
onBlur && onBlur();
const _isInvalid = isInvalid ? isInvalid(_value) : false;
if (!_isInvalid) {
onTextChanged(_value);
setIsEditing(false);
} else {
Toaster.show({
text: "Invalid name",
variant: Variant.danger,
});
}
},
[isInvalid],
);
const onInputchange = (_value: string) => {
let finalVal: string = _value;
if (props.valueTransform) {
finalVal = props.valueTransform(_value);
}
setValue(finalVal);
};
const onInputchange = useCallback(
(_value: string) => {
let finalVal: string = _value;
if (valueTransform) {
finalVal = valueTransform(_value);
}
setValue(finalVal);
},
[valueTransform],
);
const errorMessage = props.isInvalid && props.isInvalid(value);
const errorMessage = isInvalid && isInvalid(value);
const error = errorMessage ? errorMessage : undefined;
return (
<EditableTextWrapper
isEditing={isEditing}
minimal={!!props.minimal}
minimal={!!minimal}
onClick={
props.editInteractionKind === EditInteractionKind.SINGLE ? edit : _.noop
editInteractionKind === EditInteractionKind.SINGLE ? edit : _.noop
}
onDoubleClick={
props.editInteractionKind === EditInteractionKind.DOUBLE ? edit : _.noop
editInteractionKind === EditInteractionKind.DOUBLE ? edit : _.noop
}
>
<ErrorTooltip isOpen={!!error} message={errorMessage as string}>
<TextContainer isValid={!error} minimal={!!props.minimal}>
<TextContainer isValid={!error} minimal={!!minimal}>
<BlueprintEditableText
className={props.className}
className={className}
disabled={!isEditing}
isEditing={isEditing}
onCancel={props.onBlur}
onCancel={onBlur}
onChange={onInputchange}
onConfirm={onChange}
placeholder={props.placeholder}
placeholder={placeholder}
selectAllOnFocus
value={value}
/>
{!props.minimal &&
!props.hideEditIcon &&
!props.updating &&
!isEditing && <EditPen alt="Edit pen" src={Edit} />}
{!minimal && !hideEditIcon && !updating && !isEditing && (
<EditPen alt="Edit pen" src={Edit} />
)}
</TextContainer>
</ErrorTooltip>
</EditableTextWrapper>

View File

@ -4610,6 +4610,11 @@
version "4.2.2"
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
"@yarnpkg/lockfile@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
abab@^2.0.3:
version "2.0.5"
resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a"
@ -6670,7 +6675,7 @@ cross-fetch@^3.0.4:
dependencies:
node-fetch "2.6.1"
cross-spawn@6.0.5, cross-spawn@^6.0.0:
cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
dependencies:
@ -8595,6 +8600,13 @@ find-up@^2.0.0, find-up@^2.1.0:
dependencies:
locate-path "^2.0.0"
find-yarn-workspace-root@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd"
integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==
dependencies:
micromatch "^4.0.2"
flat-cache@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0"
@ -8738,7 +8750,7 @@ fs-extra@^0.30.0:
path-is-absolute "^1.0.0"
rimraf "^2.2.8"
fs-extra@^7.0.0:
fs-extra@^7.0.0, fs-extra@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
dependencies:
@ -11053,6 +11065,13 @@ kind-of@^6.0.0, kind-of@^6.0.2:
version "6.0.3"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
klaw-sync@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c"
integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==
dependencies:
graceful-fs "^4.1.11"
klaw@^1.0.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439"
@ -12525,6 +12544,14 @@ open@^7.0.0, open@^7.0.2, open@^7.1.0:
is-docker "^2.0.0"
is-wsl "^2.1.1"
open@^7.4.2:
version "7.4.2"
resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321"
integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==
dependencies:
is-docker "^2.0.0"
is-wsl "^2.1.1"
opencollective-postinstall@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259"
@ -12789,6 +12816,25 @@ pascalcase@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
patch-package@^6.4.7:
version "6.4.7"
resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.4.7.tgz#2282d53c397909a0d9ef92dae3fdeb558382b148"
integrity sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==
dependencies:
"@yarnpkg/lockfile" "^1.1.0"
chalk "^2.4.2"
cross-spawn "^6.0.5"
find-yarn-workspace-root "^2.0.0"
fs-extra "^7.0.1"
is-ci "^2.0.0"
klaw-sync "^6.0.0"
minimist "^1.2.0"
open "^7.4.2"
rimraf "^2.6.3"
semver "^5.6.0"
slash "^2.0.0"
tmp "^0.0.33"
path-browserify@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a"
@ -13606,6 +13652,11 @@ postcss@^8.1.0:
nanoid "^3.1.15"
source-map "^0.6.1"
postinstall-postinstall@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz#4f7f77441ef539d1512c40bd04c71b06a4704ca3"
integrity sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==
preact@8.2.9:
version "8.2.9"
resolved "https://registry.yarnpkg.com/preact/-/preact-8.2.9.tgz#813ba9dd45e5d97c5ea0d6c86d375b3be711cc40"