Skip to content

Commit d91fe66

Browse files
memoize comps to minimize re-rendering
1 parent 4b09509 commit d91fe66

File tree

10 files changed

+57
-40
lines changed

10 files changed

+57
-40
lines changed

client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ export type NewChildren<ChildrenCompMap extends Record<string, Comp<unknown>>> =
4444
version: InstanceType<typeof StringControl>;
4545
};
4646

47-
export function HidableView(props: {
47+
export const HidableView = React.memo((props: {
4848
children: JSX.Element | React.ReactNode;
4949
hidden: boolean;
50-
}) {
50+
}) => {
5151
const { readOnly } = useContext(ExternalEditorContext);
5252
if (readOnly) {
5353
return <>{props.children}</>;
@@ -64,15 +64,15 @@ export function HidableView(props: {
6464
</>
6565
);
6666
}
67-
}
67+
})
6868

69-
export function ExtendedPropertyView<
69+
export const ExtendedPropertyView = React.memo(<
7070
ChildrenCompMap extends Record<string, Comp<unknown>>,
7171
>(props: {
7272
children: JSX.Element | React.ReactNode,
7373
childrenMap: NewChildren<ChildrenCompMap>
7474
}
75-
) {
75+
) => {
7676
const [compVersions, setCompVersions] = useState(['latest']);
7777
const [compName, setCompName] = useState('');
7878
const editorState = useContext(EditorContext);
@@ -129,7 +129,7 @@ export function ExtendedPropertyView<
129129
)}
130130
</>
131131
);
132-
}
132+
});
133133

134134
export function uiChildren<
135135
ChildrenCompMap extends Record<string, Comp<unknown>>,
@@ -275,11 +275,11 @@ export const DisabledContext = React.createContext<boolean>(false);
275275
/**
276276
* Guaranteed to be in a react component, so that react hooks can be used internally
277277
*/
278-
function UIView(props: {
278+
const UIView = React.memo((props: {
279279
innerRef: React.RefObject<HTMLDivElement>;
280280
comp: any;
281281
viewFn: any;
282-
}) {
282+
}) => {
283283
const comp = props.comp;
284284
const childrenProps = childrenToProps(comp.children);
285285
const childrenJsonProps = comp.toJsonValue();
@@ -397,13 +397,12 @@ function UIView(props: {
397397
width: '100%',
398398
height: '100%',
399399
margin: '0px',
400-
padding:getPadding()
401-
400+
padding: getPadding()
402401
}}
403402
>
404403
<HidableView hidden={childrenProps.hidden as boolean}>
405404
{props.viewFn(childrenProps, comp.dispatch)}
406405
</HidableView>
407406
</div>
408407
);
409-
}
408+
});

client/packages/lowcoder/src/layout/compSelectionWrapper.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ const HiddenIcon = styled(CloseEyeIcon)`
231231
}
232232
`;
233233

234-
export const CompSelectionWrapper = (props: {
234+
export const CompSelectionWrapper = React.memo((props: {
235235
id?: string;
236236
compType: UICompType;
237237
className?: string;
@@ -376,4 +376,4 @@ export const CompSelectionWrapper = (props: {
376376
</SelectableDiv>
377377
</div>
378378
);
379-
};
379+
});

client/packages/lowcoder/src/layout/gridItem.tsx

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import React, {
66
ReactElement,
77
SyntheticEvent,
88
useCallback,
9+
useContext,
910
useMemo,
1011
useRef,
1112
useState,
@@ -26,6 +27,7 @@ import {
2627
setTransform,
2728
} from "./utils";
2829
import styled from "styled-components";
30+
import { EditorContext } from "@lowcoder-ee/comps/editorState";
2931

3032
type GridItemCallback<Data extends GridDragEvent | GridResizeEvent> = (
3133
i: string,
@@ -104,6 +106,7 @@ export function GridItem(props: GridItemProps) {
104106
const [resizing, setResizing] = useState<{ width: number; height: number } | undefined>();
105107
const [dragging, setDragging] = useState<{ top: number; left: number } | undefined>();
106108
const elementRef = useRef<HTMLDivElement>(null);
109+
const editorState = useContext(EditorContext);
107110

108111
// record the real height of the comp content
109112
const itemHeightRef = useRef<number | undefined>(undefined);
@@ -141,14 +144,17 @@ export function GridItem(props: GridItemProps) {
141144
onDrag={onDrag}
142145
onDragEnd={onDragEnd}
143146
onMouseDown={(e) => {
144-
e.stopPropagation();
147+
const parentContainer = editorState.findUIParentContainer(props.name!)?.toJsonValue();
145148

146149
// allow mouseDown event on lowcoder-comp-kanban to make drag/drop work
147-
if((props.compType as string).includes('lowcoder-comp-kanban')) return;
150+
if(
151+
(props.compType as string).includes('lowcoder-comp-kanban')
152+
|| parentContainer?.compType?.includes('lowcoder-comp-kanban')
153+
) return;
148154

149155
// allow mouseDown event on lowcoder-comp-excalidraw to make drag/drop work
150156
if((props.compType as string).includes('lowcoder-comp-excalidraw')) return;
151-
157+
e.stopPropagation();
152158
const event = new MouseEvent("mousedown");
153159
document.dispatchEvent(event);
154160
}}
@@ -471,11 +477,11 @@ export function GridItem(props: GridItemProps) {
471477
return renderResult;
472478
}
473479

474-
GridItem.defaultProps = {
475-
className: "",
476-
minH: 1,
477-
minW: 1,
478-
maxH: Infinity,
479-
maxW: Infinity,
480-
transformScale: 1,
481-
};
480+
// GridItem.defaultProps = {
481+
// className: "",
482+
// minH: 1,
483+
// minW: 1,
484+
// maxH: Infinity,
485+
// maxW: Infinity,
486+
// transformScale: 1,
487+
// };

client/packages/lowcoder/src/layout/gridLayout.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -471,16 +471,16 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
471471
isDraggable={isDraggable && isItemDraggable(item)}
472472
isResizable={isResizable && isItemResizable(item)}
473473
isSelectable={selectable}
474-
transformScale={transformScale}
474+
transformScale={transformScale || 1}
475475
w={item.w}
476476
h={extraItem?.hidden && !extraItem?.isSelected ? 0 : item.h}
477477
x={item.x}
478478
y={item.y}
479479
i={item.i}
480-
minH={item.minH}
481-
minW={item.minW}
482-
maxH={item.maxH}
483-
maxW={item.maxW}
480+
minH={item.minH || 1}
481+
minW={item.minW || 1}
482+
maxH={item.maxH || Infinity}
483+
maxW={item.maxW || Infinity}
484484
placeholder={item.placeholder}
485485
layoutHide={item.hide}
486486
static={item.static}
@@ -496,6 +496,7 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
496496
bottom: (showName?.bottom ?? 0) + (this.ref.current?.scrollHeight ?? 0),
497497
}}
498498
zIndex={zIndex}
499+
className=""
499500
>
500501
{child}
501502
</GridItem>

client/packages/lowcoder/src/pages/common/help.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ const introVideoUrl = trans("docUrls.introVideo");
181181
const issueUrl = trans("lowcoderUrl.createIssue");
182182
const discordUrl = trans("lowcoderUrl.discord");
183183

184-
export function HelpDropdown(props: HelpDropdownProps) {
184+
function HelpDropdownComp(props: HelpDropdownProps) {
185185
const [showHelp, setShowHelp] = useState(true);
186186
const [version, setVersion] = useState("");
187187
const dispatch = useDispatch();
@@ -446,3 +446,5 @@ export function HelpDropdown(props: HelpDropdownProps) {
446446
</HelpWrapper>
447447
</>);
448448
}
449+
450+
export const HelpDropdown = React.memo(HelpDropdownComp);

client/packages/lowcoder/src/pages/common/previewHeader.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { getBrandingConfig } from "../../redux/selectors/configSelectors";
2020
import { HeaderStartDropdown } from "./headerStartDropdown";
2121
import { useParams } from "react-router";
2222
import { AppPathParams } from "constants/applicationConstants";
23+
import React from "react";
2324

2425
const HeaderFont = styled.div<{ $bgColor: string }>`
2526
font-weight: 500;
@@ -127,7 +128,7 @@ export function HeaderProfile(props: { user: User }) {
127128
);
128129
}
129130

130-
export const PreviewHeader = () => {
131+
const PreviewHeaderComp = () => {
131132
const params = useParams<AppPathParams>();
132133
const user = useSelector(getUser);
133134
const application = useSelector(currentApplication);
@@ -203,3 +204,5 @@ export const PreviewHeader = () => {
203204
/>
204205
);
205206
};
207+
208+
export const PreviewHeader = React.memo(PreviewHeaderComp);

client/packages/lowcoder/src/pages/editor/editorHotKeys.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ function handleMouseDown(e: MouseEvent, editorState: EditorState, showLeftPanel:
113113
}
114114
}
115115

116-
export function EditorGlobalHotKeys(props: GlobalProps) {
116+
export const EditorGlobalHotKeys = React.memo((props: GlobalProps) => {
117117
const editorState = useContext(EditorContext);
118118
const { history: editorHistory } = useContext(ExternalEditorContext);
119119
const { togglePanel, panelStatus, toggleShortcutList } = props;
@@ -155,7 +155,7 @@ export function EditorGlobalHotKeys(props: GlobalProps) {
155155
children={props.children}
156156
/>
157157
);
158-
}
158+
})
159159

160160
// local hotkeys
161161
function handleEditorKeyDown(e: React.KeyboardEvent, editorState: EditorState) {
@@ -186,7 +186,7 @@ function handleEditorKeyDown(e: React.KeyboardEvent, editorState: EditorState) {
186186
}
187187
}
188188

189-
export function EditorHotKeys(props: Props) {
189+
export const EditorHotKeys = React.memo((props: Props) => {
190190
const editorState = useContext(EditorContext);
191191
const onKeyDown = useCallback(
192192
(e: React.KeyboardEvent) => handleEditorKeyDown(e, editorState),
@@ -200,9 +200,9 @@ export function EditorHotKeys(props: Props) {
200200
children={props.children}
201201
/>
202202
);
203-
}
203+
})
204204

205-
export function CustomShortcutWrapper(props: { children: React.ReactNode }) {
205+
export const CustomShortcutWrapper = React.memo((props: { children: React.ReactNode }) => {
206206
const editorState = useContext(EditorContext);
207207
const handleCustomShortcut = useCallback(
208208
(e: KeyboardEvent) => {
@@ -215,4 +215,4 @@ export function CustomShortcutWrapper(props: { children: React.ReactNode }) {
215215
{props.children}
216216
</GlobalShortcutsWrapper>
217217
);
218-
}
218+
})

client/packages/lowcoder/src/pages/editor/editorView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,4 +577,4 @@ function EditorView(props: EditorViewProps) {
577577
);
578578
}
579579

580-
export default EditorView;
580+
export default React.memo(EditorView);

client/packages/lowcoder/src/pages/editor/right/RightPanel.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { AttributeIcon } from "lowcoder-design";
99
import { InsertIcon } from "lowcoder-design";
1010
import { trans } from "i18n";
1111
import { isAggregationApp } from "util/appUtils";
12+
import React from "react";
1213

1314
type RightPanelProps = {
1415
onTabChange: (key: string) => void;
@@ -17,7 +18,7 @@ type RightPanelProps = {
1718
uiComp?: InstanceType<typeof UIComp>;
1819
};
1920

20-
export default function RightPanel(props: RightPanelProps) {
21+
function RightPanel(props: RightPanelProps) {
2122
const { onTabChange, showPropertyPane, uiComp } = props;
2223
const uiCompType = uiComp && (uiComp.children.compType.getView() as UiLayoutType);
2324
const aggregationApp = uiCompType && isAggregationApp(uiCompType);
@@ -55,3 +56,5 @@ export default function RightPanel(props: RightPanelProps) {
5556
</RightPanelWrapper>
5657
);
5758
}
59+
60+
export default React.memo(RightPanel);

client/packages/lowcoder/src/pages/tutorials/editorTutorials.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { i18nObjs } from "../../i18n/index";
3333
import { DatasourceInfo, HttpConfig } from "api/datasourceApi";
3434
import { enObj } from "i18n/locales";
3535
import { QUICK_REST_API_ID } from "constants/datasourceConstants";
36+
import React from "react";
3637

3738
const tourSteps: Step[] = [
3839
{
@@ -203,7 +204,7 @@ function addQuery(editorState: EditorState, datasourceInfos: DatasourceInfo[]) {
203204
editorState.setSelectedBottomRes(queryName, BottomResTypeEnum.Query);
204205
}
205206

206-
export default function EditorTutorials() {
207+
function EditorTutorials() {
207208
const [run, setRun] = useState(false);
208209
const [stepIndex, setStepIndex] = useState(0);
209210
const editorState = useContext(EditorContext);
@@ -309,3 +310,5 @@ export default function EditorTutorials() {
309310
/>
310311
);
311312
}
313+
314+
export default React.memo(EditorTutorials);

0 commit comments

Comments
 (0)