Skip to content

Commit 57fd2da

Browse files
ENvironmentSetanakin_karrot
andauthored
chore(react): Prioritize ongoing rendering works over anticipated next activities prefetching works. (#667)
Co-authored-by: anakin_karrot <[email protected]>
1 parent 002aebc commit 57fd2da

File tree

3 files changed

+47
-35
lines changed

3 files changed

+47
-35
lines changed

.changeset/solid-pillows-laugh.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@stackflow/react": minor
3+
---
4+
5+
Improve scheduling of Activity preparation tasks by marking them as passive effects.
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import type { RegisteredActivityName } from "@stackflow/config";
2+
import { useEffect } from "react";
23
import { usePrepare } from "./usePrepare";
34

45
export function useActivityPreparation(
56
activities: { activityName: RegisteredActivityName }[],
67
) {
78
const prepare = usePrepare();
89

9-
for (const { activityName } of activities) {
10-
prepare(activityName);
11-
}
10+
useEffect(() => {
11+
for (const { activityName } of activities) {
12+
prepare(activityName);
13+
}
14+
}, [activities, prepare]);
1215
}

integrations/react/src/future/usePrepare.ts

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type {
22
InferActivityParams,
33
RegisteredActivityName,
44
} from "@stackflow/config";
5+
import { useCallback } from "react";
56
import { useActivityComponentMap } from "../__internal__/ActivityComponentMapProvider";
67
import { isStructuredActivityComponent } from "../__internal__/StructuredActivityComponentType";
78
import { useDataLoader } from "./loader";
@@ -17,37 +18,40 @@ export function usePrepare(): Prepare {
1718
const loadData = useDataLoader();
1819
const activityComponentMap = useActivityComponentMap();
1920

20-
return async function prepare<K extends RegisteredActivityName>(
21-
activityName: K,
22-
activityParams?: InferActivityParams<K>,
23-
) {
24-
const activityConfig = config.activities.find(
25-
({ name }) => name === activityName,
26-
);
27-
const prefetchTasks: Promise<unknown>[] = [];
28-
29-
if (!activityConfig)
30-
throw new Error(`Activity ${activityName} is not registered.`);
31-
32-
if (activityParams && activityConfig.loader) {
33-
prefetchTasks.push(
34-
Promise.resolve(loadData(activityName, activityParams)),
35-
);
36-
}
37-
38-
if ("_load" in activityComponentMap[activityName]) {
39-
prefetchTasks.push(
40-
Promise.resolve(activityComponentMap[activityName]._load?.()),
41-
);
42-
}
43-
44-
if (
45-
isStructuredActivityComponent(activityComponentMap[activityName]) &&
46-
typeof activityComponentMap[activityName].content === "function"
21+
return useCallback(
22+
async function prepare<K extends RegisteredActivityName>(
23+
activityName: K,
24+
activityParams?: InferActivityParams<K>,
4725
) {
48-
prefetchTasks.push(activityComponentMap[activityName].content());
49-
}
50-
51-
await Promise.all(prefetchTasks);
52-
};
26+
const activityConfig = config.activities.find(
27+
({ name }) => name === activityName,
28+
);
29+
const prefetchTasks: Promise<unknown>[] = [];
30+
31+
if (!activityConfig)
32+
throw new Error(`Activity ${activityName} is not registered.`);
33+
34+
if (activityParams && activityConfig.loader) {
35+
prefetchTasks.push(
36+
Promise.resolve(loadData(activityName, activityParams)),
37+
);
38+
}
39+
40+
if ("_load" in activityComponentMap[activityName]) {
41+
prefetchTasks.push(
42+
Promise.resolve(activityComponentMap[activityName]._load?.()),
43+
);
44+
}
45+
46+
if (
47+
isStructuredActivityComponent(activityComponentMap[activityName]) &&
48+
typeof activityComponentMap[activityName].content === "function"
49+
) {
50+
prefetchTasks.push(activityComponentMap[activityName].content());
51+
}
52+
53+
await Promise.all(prefetchTasks);
54+
},
55+
[config, loadData, activityComponentMap],
56+
);
5357
}

0 commit comments

Comments
 (0)