fix(core): improve tag list performance (#11353)

This commit is contained in:
EYHN
2025-04-01 08:48:09 +00:00
parent ab60203849
commit 275098abe2
6 changed files with 40 additions and 20 deletions
@@ -407,7 +407,6 @@ function tagMetaToListItemProp(
to: props.rowAsLink && !props.selectable ? `/tag/${item.id}` : undefined,
onClick: toggleSelection,
color: item.color,
pageCount: item.pageCount,
operations: props.operationsRenderer?.(item),
selectable: props.selectable,
selected: props.selectedIds?.includes(item.id),
@@ -11,9 +11,7 @@ import type { TagListItemProps } from '../types';
import { ColWrapper } from '../utils';
import * as styles from './tag-list-item.css';
const TagListTitleCell = ({
title,
}: Pick<TagListItemProps, 'title' | 'pageCount'>) => {
const TagListTitleCell = ({ title }: Pick<TagListItemProps, 'title'>) => {
const t = useI18n();
return (
<div data-testid="tag-list-item-title" className={styles.titleCell}>
@@ -119,7 +117,7 @@ export const TagListItem = (props: TagListItemProps) => {
/>
<ListIconCell color={props.color} />
</div>
<TagListTitleCell title={props.title} pageCount={props.pageCount} />
<TagListTitleCell title={props.title} />
</ColWrapper>
<ColWrapper
flex={4}
@@ -147,7 +145,7 @@ export const TagListItem = (props: TagListItemProps) => {
/>
<ListIconCell color={props.color} />
</div>
<TagListTitleCell title={props.title} pageCount={props.pageCount} />
<TagListTitleCell title={props.title} />
</div>
</CustomDragPreview>
</>
@@ -59,7 +59,6 @@ export type TagListItemProps = {
tagId: string;
color: string;
title: ReactNode; // using ReactNode to allow for rich content rendering
pageCount?: number;
createDate?: Date | number;
updatedDate?: Date | number;
to?: To; // whether or not to render this item as a Link
@@ -60,7 +60,6 @@ export class TagList extends Entity {
id: tag.id,
title: get(tag.value$),
color: get(tag.color$),
pageCount: get(tag.pageIds$).length,
createDate: get(tag.createDate$),
updatedDate: get(tag.updateDate$),
};
@@ -64,14 +64,5 @@ 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
.filter(page => get(page.meta$).tags?.includes(this.id))
.map(page => page.id);
});
readonly pageIds$ = LiveData.from(this.store.watchTagPageIds(this.id), []);
}
@@ -1,8 +1,14 @@
import type { Tag, Tag as TagSchema } from '@affine/env/filter';
import type { DocsPropertiesMeta } from '@blocksuite/affine/store';
import { LiveData, Store } from '@toeverything/infra';
import {
LiveData,
Store,
yjsObserveByPath,
yjsObserveDeep,
} from '@toeverything/infra';
import { nanoid } from 'nanoid';
import { Observable } from 'rxjs';
import { map, Observable, switchMap } from 'rxjs';
import { Array as YArray } from 'yjs';
import type { WorkspaceService } from '../../workspace';
@@ -119,4 +125,32 @@ export class TagStore extends Store {
...tagInfo,
});
}
watchTagPageIds(id: string) {
return yjsObserveByPath(
this.workspaceService.workspace.rootYDoc.getMap('meta'),
'pages'
).pipe(
switchMap(yjsObserveDeep),
map(meta => {
if (meta instanceof YArray) {
return meta
.map(v => {
const tags = v.get('tags') as YArray<string> | undefined;
if (tags instanceof YArray) {
for (const tagId of tags.toArray()) {
if (tagId === id) {
return v.get('id') as string;
}
}
}
return null;
})
.filter(Boolean) as string[];
} else {
return [];
}
})
);
}
}