From 1b4d65fd6434dba4bb8457db428aa2567befab80 Mon Sep 17 00:00:00 2001 From: EYHN Date: Mon, 29 Jul 2024 09:57:40 +0000 Subject: [PATCH] fix(core): optimize sidebar tag performance (#7633) --- .../explorer/views/nodes/tag/index.tsx | 33 ++++++++++++------- .../core/src/modules/tag/entities/tag-list.ts | 12 ++++++- .../core/src/modules/tag/entities/tag.ts | 4 +++ 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/packages/frontend/core/src/modules/explorer/views/nodes/tag/index.tsx b/packages/frontend/core/src/modules/explorer/views/nodes/tag/index.tsx index 3da8ecac13..3afa6c5ff8 100644 --- a/packages/frontend/core/src/modules/explorer/views/nodes/tag/index.tsx +++ b/packages/frontend/core/src/modules/explorer/views/nodes/tag/index.tsx @@ -3,6 +3,7 @@ import { type DropTargetOptions, toast, } from '@affine/component'; +import type { Tag } from '@affine/core/modules/tag'; import { TagService } from '@affine/core/modules/tag'; import type { AffineDNDData } from '@affine/core/types/dnd'; import { useI18n } from '@affine/i18n'; @@ -46,7 +47,6 @@ export const ExplorerTagNode = ({ const tagRecord = useLiveData(tagService.tagList.tagByTagId$(tagId)); const tagColor = useLiveData(tagRecord?.color$); const tagName = useLiveData(tagRecord?.value$); - const tagDocIds = useLiveData(tagRecord?.pageIds$); const Icon = useCallback( ({ className }: { className?: string }) => { @@ -181,16 +181,27 @@ export const ExplorerTagNode = ({ dropEffect={handleDropEffectOnTag} data-testid={`explorer-tag-${tagId}`} > - {tagDocIds?.map(docId => ( - - ))} + ); }; + +/** + * the `tag.pageIds$` has a performance issue, + * so we split the tag node children into a separate component, + * so it won't be rendered when the tag node is collapsed. + */ +export const ExplorerTagNodeDocs = ({ tag }: { tag: Tag }) => { + const tagDocIds = useLiveData(tag.pageIds$); + + return tagDocIds.map(docId => ( + + )); +}; diff --git a/packages/frontend/core/src/modules/tag/entities/tag-list.ts b/packages/frontend/core/src/modules/tag/entities/tag-list.ts index 8edae7d2c5..efc5f473ff 100644 --- a/packages/frontend/core/src/modules/tag/entities/tag-list.ts +++ b/packages/frontend/core/src/modules/tag/entities/tag-list.ts @@ -12,8 +12,18 @@ export class TagList extends Entity { super(); } + private readonly pool = new Map(); + readonly tags$ = LiveData.from(this.store.watchTagIds(), []).map(ids => { - return ids.map(id => this.framework.createEntity(Tag, { id })); + return ids.map(id => { + const exists = this.pool.get(id); + if (exists) { + return exists; + } + const record = this.framework.createEntity(Tag, { id }); + this.pool.set(id, record); + return record; + }); }); createTag(value: string, color: string) { diff --git a/packages/frontend/core/src/modules/tag/entities/tag.ts b/packages/frontend/core/src/modules/tag/entities/tag.ts index 0d5018a516..f963fa59b7 100644 --- a/packages/frontend/core/src/modules/tag/entities/tag.ts +++ b/packages/frontend/core/src/modules/tag/entities/tag.ts @@ -62,6 +62,10 @@ export class Tag extends Entity<{ id: string }> { }); } + /** + * @deprecated performance issue here, use with caution until it is fixed + * @fixme(EYHN): page.meta$ has performance issue + */ readonly pageIds$ = LiveData.computed(get => { const pages = get(this.docs.list.docs$); return pages