perf: 分批渲染仓库列表减少排序卡顿

This commit is contained in:
EmberSparks 2026-03-02 19:38:39 +08:00
parent cf8890c08c
commit 8d9eeb0303

View file

@ -80,6 +80,7 @@ export class GithubStarsView extends ItemView {
virtualItemsEl: HTMLElement | null = null;
virtualBottomSpacerEl: HTMLElement | null = null;
virtualMeasureFrameId: number | null = null;
repoRenderVersion: number = 0;
constructor(leaf: WorkspaceLeaf, plugin: GithubStarsPlugin) {
super(leaf);
@ -394,6 +395,26 @@ export class GithubStarsView extends ItemView {
this.renderVirtualizedWindow();
};
/**
* DOM 线
*/
private waitForNextFrame(): Promise<void> {
return new Promise((resolve) => {
window.requestAnimationFrame(() => resolve());
});
}
/**
*
*/
private getRepoRenderBatchSize(totalCount: number): number {
if (totalCount > 1400) return 10;
if (totalCount > 900) return 14;
if (totalCount > 500) return 20;
if (totalCount > 220) return 28;
return 36;
}
/**
*
*/
@ -958,6 +979,8 @@ export class GithubStarsView extends ItemView {
console.warn('repoContainer not initialized');
return;
}
const renderVersion = ++this.repoRenderVersion;
if (!this.githubRepositories || this.githubRepositories.length === 0) {
this.disableRepoVirtualization();
this.repoContainer.empty();
@ -979,11 +1002,11 @@ export class GithubStarsView extends ItemView {
this.updateTotalStarsCount(sortedRepos.length);
if (sortedRepos.length < REPO_VIRTUALIZATION_THRESHOLD) {
this.renderFullRepositories(sortedRepos);
void this.renderFullRepositories(sortedRepos, renderVersion);
return;
}
this.renderVirtualizedRepositories(sortedRepos);
this.renderVirtualizedRepositories(sortedRepos, renderVersion);
}
/**
@ -1071,20 +1094,37 @@ export class GithubStarsView extends ItemView {
/**
*
*/
private renderFullRepositories(repositories: RenderRepository[]): void {
private async renderFullRepositories(repositories: RenderRepository[], renderVersion: number): Promise<void> {
if (!this.repoContainer) return;
this.disableRepoVirtualization();
this.repoContainer.empty();
repositories.forEach((repo) => {
this.renderRepositoryCard(repo, this.repoContainer);
});
const batchSize = this.getRepoRenderBatchSize(repositories.length);
for (let start = 0; start < repositories.length; start += batchSize) {
if (renderVersion !== this.repoRenderVersion || !this.repoContainer) {
return;
}
const end = Math.min(repositories.length, start + batchSize);
for (let index = start; index < end; index++) {
if (renderVersion !== this.repoRenderVersion || !this.repoContainer) {
return;
}
this.renderRepositoryCard(repositories[index], this.repoContainer);
}
if (end < repositories.length) {
await this.waitForNextFrame();
}
}
}
/**
*
*/
private renderVirtualizedRepositories(repositories: RenderRepository[]): void {
private renderVirtualizedRepositories(repositories: RenderRepository[], renderVersion: number): void {
if (!this.repoContainer) return;
if (renderVersion !== this.repoRenderVersion) return;
this.virtualizedRepos = repositories;
if (!this.isRepoListVirtualized || !this.virtualItemsEl || !this.virtualTopSpacerEl || !this.virtualBottomSpacerEl) {
@ -2010,6 +2050,7 @@ export class GithubStarsView extends ItemView {
}
onClose(): Promise<void> {
this.repoRenderVersion += 1;
if (this.repoContainer) {
this.repoContainer.removeEventListener('scroll', this.handleRepoContainerScroll);
}