mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-09-20 07:57:29 +03:00
perf(core): load all pages after 10s (#4834)
This commit is contained in:
parent
61dc4a56f9
commit
7e381e830a
@ -59,7 +59,7 @@
|
|||||||
"@blocksuite/global": "0.0.0-20231101080734-aa27dc89-nightly",
|
"@blocksuite/global": "0.0.0-20231101080734-aa27dc89-nightly",
|
||||||
"@blocksuite/store": "0.0.0-20231101080734-aa27dc89-nightly",
|
"@blocksuite/store": "0.0.0-20231101080734-aa27dc89-nightly",
|
||||||
"jotai": "^2.4.3",
|
"jotai": "^2.4.3",
|
||||||
"jotai-effect": "^0.1.0",
|
"jotai-effect": "^0.2.2",
|
||||||
"tinykeys": "^2.1.0",
|
"tinykeys": "^2.1.0",
|
||||||
"zod": "^3.22.4"
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
|
@ -6,6 +6,8 @@ import { ReferencePage } from '../components/reference-page';
|
|||||||
import type { FavoriteListProps } from '../index';
|
import type { FavoriteListProps } from '../index';
|
||||||
import EmptyItem from './empty-item';
|
import EmptyItem from './empty-item';
|
||||||
|
|
||||||
|
const emptyPageIdSet = new Set<string>();
|
||||||
|
|
||||||
export const FavoriteList = ({ workspace }: FavoriteListProps) => {
|
export const FavoriteList = ({ workspace }: FavoriteListProps) => {
|
||||||
const metas = useBlockSuitePageMeta(workspace);
|
const metas = useBlockSuitePageMeta(workspace);
|
||||||
|
|
||||||
@ -35,7 +37,7 @@ export const FavoriteList = ({ workspace }: FavoriteListProps) => {
|
|||||||
metaMapping={metaMapping}
|
metaMapping={metaMapping}
|
||||||
pageId={pageMeta.id}
|
pageId={pageMeta.id}
|
||||||
// memo?
|
// memo?
|
||||||
parentIds={new Set()}
|
parentIds={emptyPageIdSet}
|
||||||
workspace={workspace}
|
workspace={workspace}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
rootWorkspacesMetadataAtom,
|
rootWorkspacesMetadataAtom,
|
||||||
} from '@affine/workspace/atom';
|
} from '@affine/workspace/atom';
|
||||||
import { assertExists } from '@blocksuite/global/utils';
|
import { assertExists } from '@blocksuite/global/utils';
|
||||||
|
import type { Page } from '@blocksuite/store';
|
||||||
import type { DragEndEvent } from '@dnd-kit/core';
|
import type { DragEndEvent } from '@dnd-kit/core';
|
||||||
import {
|
import {
|
||||||
DndContext,
|
DndContext,
|
||||||
@ -29,6 +30,7 @@ import {
|
|||||||
useSensors,
|
useSensors,
|
||||||
} from '@dnd-kit/core';
|
} from '@dnd-kit/core';
|
||||||
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
|
import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta';
|
||||||
|
import { loadPage } from '@toeverything/hooks/use-block-suite-workspace-page';
|
||||||
import { currentWorkspaceIdAtom } from '@toeverything/infra/atom';
|
import { currentWorkspaceIdAtom } from '@toeverything/infra/atom';
|
||||||
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
|
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
@ -119,6 +121,29 @@ type WorkspaceLayoutProps = {
|
|||||||
incompatible?: boolean;
|
incompatible?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// fix https://github.com/toeverything/AFFiNE/issues/4825
|
||||||
|
function useLoadWorkspacePages() {
|
||||||
|
const [currentWorkspace] = useCurrentWorkspace();
|
||||||
|
const pageMetas = useBlockSuitePageMeta(currentWorkspace.blockSuiteWorkspace);
|
||||||
|
useEffect(() => {
|
||||||
|
if (currentWorkspace) {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
const pageIds = pageMetas.map(meta => meta.id);
|
||||||
|
const pages = pageIds
|
||||||
|
.map(id => currentWorkspace.blockSuiteWorkspace.getPage(id))
|
||||||
|
.filter((p): p is Page => !!p);
|
||||||
|
pages.forEach(page => {
|
||||||
|
loadPage(page, -10);
|
||||||
|
});
|
||||||
|
}, 10 * 1000); // load pages after 10s
|
||||||
|
return () => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}, [currentWorkspace, pageMetas]);
|
||||||
|
}
|
||||||
|
|
||||||
export const WorkspaceLayout = function WorkspacesSuspense({
|
export const WorkspaceLayout = function WorkspacesSuspense({
|
||||||
children,
|
children,
|
||||||
incompatible = false,
|
incompatible = false,
|
||||||
@ -237,6 +262,8 @@ export const WorkspaceLayoutInner = ({
|
|||||||
const inTrashPage = pageMeta?.trash ?? false;
|
const inTrashPage = pageMeta?.trash ?? false;
|
||||||
const setMainContainer = useSetAtom(mainContainerAtom);
|
const setMainContainer = useSetAtom(mainContainerAtom);
|
||||||
|
|
||||||
|
useLoadWorkspacePages();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* This DndContext is used for drag page from all-pages list into a folder in sidebar */}
|
{/* This DndContext is used for drag page from all-pages list into a folder in sidebar */}
|
||||||
|
@ -9,11 +9,13 @@
|
|||||||
"foxact": "^0.2.20",
|
"foxact": "^0.2.20",
|
||||||
"jotai": "^2.4.3",
|
"jotai": "^2.4.3",
|
||||||
"lodash.debounce": "^4.0.8",
|
"lodash.debounce": "^4.0.8",
|
||||||
|
"p-queue": "^7.4.1",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"swr": "2.2.4",
|
"swr": "2.2.4",
|
||||||
"uuid": "^9.0.1"
|
"uuid": "^9.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@affine/debug": "workspace:*",
|
||||||
"@affine/env": "workspace:*",
|
"@affine/env": "workspace:*",
|
||||||
"@blocksuite/block-std": "0.0.0-20231101080734-aa27dc89-nightly",
|
"@blocksuite/block-std": "0.0.0-20231101080734-aa27dc89-nightly",
|
||||||
"@blocksuite/blocks": "0.0.0-20231101080734-aa27dc89-nightly",
|
"@blocksuite/blocks": "0.0.0-20231101080734-aa27dc89-nightly",
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
|
import { DebugLogger } from '@affine/debug';
|
||||||
import { assertExists, DisposableGroup } from '@blocksuite/global/utils';
|
import { assertExists, DisposableGroup } from '@blocksuite/global/utils';
|
||||||
import type { Page, Workspace } from '@blocksuite/store';
|
import type { Page, Workspace } from '@blocksuite/store';
|
||||||
import type { Atom } from 'jotai';
|
import type { Atom } from 'jotai';
|
||||||
import { atom, useAtomValue } from 'jotai';
|
import { atom, useAtomValue } from 'jotai';
|
||||||
|
import PQueue from 'p-queue';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
|
const logger = new DebugLogger('use-block-suite-workspace-page');
|
||||||
|
|
||||||
const weakMap = new WeakMap<Workspace, Map<string, Atom<Page | null>>>();
|
const weakMap = new WeakMap<Workspace, Map<string, Atom<Page | null>>>();
|
||||||
|
|
||||||
const emptyAtom = atom<Page | null>(null);
|
const emptyAtom = atom<Page | null>(null);
|
||||||
@ -45,6 +49,52 @@ function getAtom(w: Workspace, pageId: string | null): Atom<Page | null> {
|
|||||||
return map.get(pageId) as Atom<Page | null>;
|
return map.get(pageId) as Atom<Page | null>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// concurrently load 3 pages at most
|
||||||
|
const CONCURRENT_JOBS = 3;
|
||||||
|
|
||||||
|
const loadPageQueue = new PQueue({
|
||||||
|
concurrency: CONCURRENT_JOBS,
|
||||||
|
});
|
||||||
|
|
||||||
|
const loadedPages = new WeakSet<Page>();
|
||||||
|
|
||||||
|
const awaitForIdle = () =>
|
||||||
|
new Promise(resolve =>
|
||||||
|
requestIdleCallback(resolve, {
|
||||||
|
timeout: 1000, // do not wait for too long
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const awaitForTimeout = (timeout: number) =>
|
||||||
|
new Promise(resolve => setTimeout(resolve, timeout));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a page and wait for it to be loaded
|
||||||
|
* This page will be loaded in a queue so that it will not jam the network and browser CPU
|
||||||
|
*/
|
||||||
|
export function loadPage(page: Page, priority = 0) {
|
||||||
|
if (loadedPages.has(page)) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
loadedPages.add(page);
|
||||||
|
return loadPageQueue.add(
|
||||||
|
async () => {
|
||||||
|
if (!page.loaded) {
|
||||||
|
await awaitForIdle();
|
||||||
|
await page.waitForLoaded();
|
||||||
|
// we do not know how long it takes to load a page here
|
||||||
|
// so that we just use 300ms timeout as the default page processing time
|
||||||
|
await awaitForTimeout(300);
|
||||||
|
logger.debug('page loaded', page.id);
|
||||||
|
} else {
|
||||||
|
// do nothing if it is already loaded
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
priority,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function useBlockSuiteWorkspacePage(
|
export function useBlockSuiteWorkspacePage(
|
||||||
blockSuiteWorkspace: Workspace,
|
blockSuiteWorkspace: Workspace,
|
||||||
@ -55,8 +105,10 @@ export function useBlockSuiteWorkspacePage(
|
|||||||
const page = useAtomValue(pageAtom);
|
const page = useAtomValue(pageAtom);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!page?.loaded) {
|
if (page && !page.loaded) {
|
||||||
page?.waitForLoaded().catch(console.error);
|
loadPage(page).catch(err => {
|
||||||
|
logger.error('Failed to load page', err);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, [page]);
|
}, [page]);
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
},
|
},
|
||||||
"references": [
|
"references": [
|
||||||
{ "path": "../../common/env" },
|
{ "path": "../../common/env" },
|
||||||
{ "path": "../../common/y-indexeddb" }
|
{ "path": "../../common/y-indexeddb" },
|
||||||
|
{ "path": "../../common/debug" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
23
yarn.lock
23
yarn.lock
@ -12509,6 +12509,7 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@toeverything/hooks@workspace:packages/frontend/hooks"
|
resolution: "@toeverything/hooks@workspace:packages/frontend/hooks"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@affine/debug": "workspace:*"
|
||||||
"@affine/env": "workspace:*"
|
"@affine/env": "workspace:*"
|
||||||
"@blocksuite/block-std": "npm:0.0.0-20231101080734-aa27dc89-nightly"
|
"@blocksuite/block-std": "npm:0.0.0-20231101080734-aa27dc89-nightly"
|
||||||
"@blocksuite/blocks": "npm:0.0.0-20231101080734-aa27dc89-nightly"
|
"@blocksuite/blocks": "npm:0.0.0-20231101080734-aa27dc89-nightly"
|
||||||
@ -12522,6 +12523,7 @@ __metadata:
|
|||||||
foxact: "npm:^0.2.20"
|
foxact: "npm:^0.2.20"
|
||||||
jotai: "npm:^2.4.3"
|
jotai: "npm:^2.4.3"
|
||||||
lodash.debounce: "npm:^4.0.8"
|
lodash.debounce: "npm:^4.0.8"
|
||||||
|
p-queue: "npm:^7.4.1"
|
||||||
react: "npm:18.2.0"
|
react: "npm:18.2.0"
|
||||||
swr: "npm:2.2.4"
|
swr: "npm:2.2.4"
|
||||||
uuid: "npm:^9.0.1"
|
uuid: "npm:^9.0.1"
|
||||||
@ -12571,7 +12573,7 @@ __metadata:
|
|||||||
async-call-rpc: "npm:^6.3.1"
|
async-call-rpc: "npm:^6.3.1"
|
||||||
electron: "link:../../frontend/electron/node_modules/electron"
|
electron: "link:../../frontend/electron/node_modules/electron"
|
||||||
jotai: "npm:^2.4.3"
|
jotai: "npm:^2.4.3"
|
||||||
jotai-effect: "npm:^0.1.0"
|
jotai-effect: "npm:^0.2.2"
|
||||||
nanoid: "npm:^5.0.1"
|
nanoid: "npm:^5.0.1"
|
||||||
react: "npm:^18.2.0"
|
react: "npm:^18.2.0"
|
||||||
rxjs: "npm:^7.8.1"
|
rxjs: "npm:^7.8.1"
|
||||||
@ -24423,15 +24425,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"jotai-effect@npm:^0.1.0":
|
|
||||||
version: 0.1.0
|
|
||||||
resolution: "jotai-effect@npm:0.1.0"
|
|
||||||
peerDependencies:
|
|
||||||
jotai: ">=2.4.3"
|
|
||||||
checksum: 38d87a3c64dfd9e1b9467b9b589947f03fdd29134f950bb11591cd335a670ce6cd13261e7e7bc4c0c9852ce0f663be215aa469c43f974ab1ef8823828e81db3d
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"jotai-effect@npm:^0.2.2":
|
"jotai-effect@npm:^0.2.2":
|
||||||
version: 0.2.2
|
version: 0.2.2
|
||||||
resolution: "jotai-effect@npm:0.2.2"
|
resolution: "jotai-effect@npm:0.2.2"
|
||||||
@ -28490,6 +28483,16 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"p-queue@npm:^7.4.1":
|
||||||
|
version: 7.4.1
|
||||||
|
resolution: "p-queue@npm:7.4.1"
|
||||||
|
dependencies:
|
||||||
|
eventemitter3: "npm:^5.0.1"
|
||||||
|
p-timeout: "npm:^5.0.2"
|
||||||
|
checksum: 82934551f20a38cc19b31cda7200f2db93ca99b8c642d3ac861d12a7a9160eb32235738a8cd53f1a7ea0c7b52d6c0bb27644b6461e9a51e6a59f1e8d65904b78
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"p-retry@npm:4, p-retry@npm:^4.5.0":
|
"p-retry@npm:4, p-retry@npm:^4.5.0":
|
||||||
version: 4.6.2
|
version: 4.6.2
|
||||||
resolution: "p-retry@npm:4.6.2"
|
resolution: "p-retry@npm:4.6.2"
|
||||||
|
Loading…
Reference in New Issue
Block a user