From 9fb5e0db63e48c915d184cc070c5cf5a7041f2c5 Mon Sep 17 00:00:00 2001 From: CatsJuice Date: Mon, 23 Dec 2024 07:07:57 +0000 Subject: [PATCH] perf(core): optimize scrolling performance for doc list (#9250) - before ![CleanShot 2024-12-23 at 14.45.47.gif](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/LakojjjzZNf6ogjOVwKE/3e62773f-00f8-4464-a342-c3cd5c5b6edb.gif) - after ![CleanShot 2024-12-23 at 14.46.22.gif](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/LakojjjzZNf6ogjOVwKE/d713ea5e-ba2d-4251-b93a-a1d0ececc7eb.gif) --- .../page-list/docs/virtualized-page-list.tsx | 8 +++---- .../src/components/page-list/page-group.tsx | 22 ++++++++++--------- .../src/components/page-list/page-header.tsx | 8 +++---- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/packages/frontend/core/src/components/page-list/docs/virtualized-page-list.tsx b/packages/frontend/core/src/components/page-list/docs/virtualized-page-list.tsx index 32aa9164fe..68e0f1c6ba 100644 --- a/packages/frontend/core/src/components/page-list/docs/virtualized-page-list.tsx +++ b/packages/frontend/core/src/components/page-list/docs/virtualized-page-list.tsx @@ -8,7 +8,7 @@ import type { Collection, Filter } from '@affine/env/filter'; import { Trans, useI18n } from '@affine/i18n'; import type { DocMeta } from '@blocksuite/affine/store'; import { useService } from '@toeverything/infra'; -import { useCallback, useMemo, useRef, useState } from 'react'; +import { memo, useCallback, useMemo, useRef, useState } from 'react'; import { ListFloatingToolbar } from '../components/list-floating-toolbar'; import { usePageItemGroupDefinitions } from '../group-definitions'; @@ -50,7 +50,7 @@ const usePageOperationsRenderer = () => { return pageOperationsRenderer; }; -export const VirtualizedPageList = ({ +export const VirtualizedPageList = memo(function VirtualizedPageList({ tag, collection, filters, @@ -62,7 +62,7 @@ export const VirtualizedPageList = ({ filters?: Filter[]; listItem?: DocMeta[]; setHideHeaderCreateNewPage?: (hide: boolean) => void; -}) => { +}) { const t = useI18n(); const listRef = useRef(null); const [showFloatingToolbar, setShowFloatingToolbar] = useState(false); @@ -202,4 +202,4 @@ export const VirtualizedPageList = ({ /> ); -}; +}); diff --git a/packages/frontend/core/src/components/page-list/page-group.tsx b/packages/frontend/core/src/components/page-list/page-group.tsx index 7f6524c922..50cfa84760 100644 --- a/packages/frontend/core/src/components/page-list/page-group.tsx +++ b/packages/frontend/core/src/components/page-list/page-group.tsx @@ -36,11 +36,9 @@ import type { } from './types'; import { shallowEqual } from './utils'; -export const ItemGroupHeader = ({ - id, - items, - label, -}: ItemGroupProps) => { +export const ItemGroupHeader = memo(function ItemGroupHeader< + T extends ListItem, +>({ id, items, label }: ItemGroupProps) { const [collapseState, setCollapseState] = useAtom(groupCollapseStateAtom); const collapsed = collapseState[id]; const onExpandedClicked: MouseEventHandler = useCallback( @@ -113,7 +111,7 @@ export const ItemGroupHeader = ({ ) : null; -}; +}); export const ItemGroup = ({ id, @@ -218,7 +216,9 @@ const listsPropsAtom = selectAtom( shallowEqual ); -export const PageListItemRenderer = (item: ListItem) => { +export const PageListItemRenderer = memo(function PageListItemRenderer( + item: ListItem +) { const props = useAtomValue(listsPropsAtom); const { selectionActive } = useAtomValue(selectionStateAtom); const groups = useAtomValue(groupsAtom); @@ -238,7 +238,7 @@ export const PageListItemRenderer = (item: ListItem) => { )} /> ); -}; +}); export const CollectionListItemRenderer = memo((item: ListItem) => { const props = useAtomValue(listsPropsAtom); @@ -256,7 +256,9 @@ export const CollectionListItemRenderer = memo((item: ListItem) => { CollectionListItemRenderer.displayName = 'CollectionListItemRenderer'; -export const TagListItemRenderer = (item: ListItem) => { +export const TagListItemRenderer = memo(function TagListItemRenderer( + item: ListItem +) { const props = useAtomValue(listsPropsAtom); const { selectionActive } = useAtomValue(selectionStateAtom); const tag = item as TagMeta; @@ -268,7 +270,7 @@ export const TagListItemRenderer = (item: ListItem) => { })} /> ); -}; +}); function tagIdToTagOption( tagId: string, diff --git a/packages/frontend/core/src/components/page-list/page-header.tsx b/packages/frontend/core/src/components/page-list/page-header.tsx index a37d05c503..88e8e09733 100644 --- a/packages/frontend/core/src/components/page-list/page-header.tsx +++ b/packages/frontend/core/src/components/page-list/page-header.tsx @@ -6,7 +6,7 @@ import { MultiSelectIcon } from '@blocksuite/icons/rc'; import clsx from 'clsx'; import { selectAtom } from 'jotai/utils'; import type { MouseEventHandler } from 'react'; -import { useCallback } from 'react'; +import { memo, useCallback } from 'react'; import { ListHeaderCell } from './components/list-header-cell'; import * as styles from './page-header.css'; @@ -82,11 +82,11 @@ export const ListHeaderTitleCell = () => { const hideHeaderAtom = selectAtom(listPropsAtom, props => props?.hideHeader); // the table header for page list -export const ListTableHeader = ({ +export const ListTableHeader = memo(function ListTableHeader({ headerCols, }: { headerCols: HeaderColDef[]; -}) => { +}) { const [sorter, setSorter] = useAtom(sorterAtom); const hideHeader = useAtomValue(hideHeaderAtom); const selectionState = useAtomValue(selectionStateAtom); @@ -136,4 +136,4 @@ export const ListTableHeader = ({ })} ); -}; +});