mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-27 02:42:25 +08:00
fix(core): optimize sidebar tag performance (#7633)
This commit is contained in:
@@ -3,6 +3,7 @@ import {
|
|||||||
type DropTargetOptions,
|
type DropTargetOptions,
|
||||||
toast,
|
toast,
|
||||||
} from '@affine/component';
|
} from '@affine/component';
|
||||||
|
import type { Tag } from '@affine/core/modules/tag';
|
||||||
import { TagService } from '@affine/core/modules/tag';
|
import { TagService } from '@affine/core/modules/tag';
|
||||||
import type { AffineDNDData } from '@affine/core/types/dnd';
|
import type { AffineDNDData } from '@affine/core/types/dnd';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
@@ -46,7 +47,6 @@ export const ExplorerTagNode = ({
|
|||||||
const tagRecord = useLiveData(tagService.tagList.tagByTagId$(tagId));
|
const tagRecord = useLiveData(tagService.tagList.tagByTagId$(tagId));
|
||||||
const tagColor = useLiveData(tagRecord?.color$);
|
const tagColor = useLiveData(tagRecord?.color$);
|
||||||
const tagName = useLiveData(tagRecord?.value$);
|
const tagName = useLiveData(tagRecord?.value$);
|
||||||
const tagDocIds = useLiveData(tagRecord?.pageIds$);
|
|
||||||
|
|
||||||
const Icon = useCallback(
|
const Icon = useCallback(
|
||||||
({ className }: { className?: string }) => {
|
({ className }: { className?: string }) => {
|
||||||
@@ -181,16 +181,27 @@ export const ExplorerTagNode = ({
|
|||||||
dropEffect={handleDropEffectOnTag}
|
dropEffect={handleDropEffectOnTag}
|
||||||
data-testid={`explorer-tag-${tagId}`}
|
data-testid={`explorer-tag-${tagId}`}
|
||||||
>
|
>
|
||||||
{tagDocIds?.map(docId => (
|
<ExplorerTagNodeDocs tag={tagRecord} />
|
||||||
<ExplorerDocNode
|
|
||||||
key={docId}
|
|
||||||
docId={docId}
|
|
||||||
reorderable={false}
|
|
||||||
location={{
|
|
||||||
at: 'explorer:tags:docs',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</ExplorerTreeNode>
|
</ExplorerTreeNode>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 => (
|
||||||
|
<ExplorerDocNode
|
||||||
|
key={docId}
|
||||||
|
docId={docId}
|
||||||
|
reorderable={false}
|
||||||
|
location={{
|
||||||
|
at: 'explorer:tags:docs',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|||||||
@@ -12,8 +12,18 @@ export class TagList extends Entity {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly pool = new Map<string, Tag>();
|
||||||
|
|
||||||
readonly tags$ = LiveData.from(this.store.watchTagIds(), []).map(ids => {
|
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) {
|
createTag(value: string, color: string) {
|
||||||
|
|||||||
@@ -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 => {
|
readonly pageIds$ = LiveData.computed(get => {
|
||||||
const pages = get(this.docs.list.docs$);
|
const pages = get(this.docs.list.docs$);
|
||||||
return pages
|
return pages
|
||||||
|
|||||||
Reference in New Issue
Block a user