perf: speed up auto-connect workspace bootstrap
Some checks failed
StoryForge CI / Baseline checks (push) Has been cancelled
StoryForge CI / Backend tests (push) Has been cancelled
StoryForge CI / Web tests (push) Has been cancelled

This commit is contained in:
kris
2026-04-06 09:30:41 +08:00
parent 0185106932
commit 1395493208
3 changed files with 18 additions and 2 deletions

View File

@@ -4,6 +4,12 @@
## 2026-04-06
### 自动连接首屏再提速一层
- 自动连接成功后,`/v2/me``/v2/me/dashboard` 现在改成并行请求,不再串行等待。
- 会话拿到以后页面会更快进入真实项目总台和当前工作区骨架再继续后台补齐账号、存储、Agent 控制面等重数据。
- 这让“点开就能用”的体验更接近真实可交互,而不是长时间停在连接提示上。
### 自动连接工作区改成先可用后补水
- 自动连接成功后不再把账号详情、存储、Agent 控制面、OneLiner 消息、文档等重数据全部串在首屏可用之前。

View File

@@ -3000,7 +3000,11 @@ async function bootstrap() {
}
setBusy(true, "正在同步工作区...");
try {
appState.me = await storyforgeFetch("/v2/me");
const [me, dashboard] = await Promise.all([
storyforgeFetch("/v2/me"),
storyforgeFetch("/v2/me/dashboard")
]);
appState.me = me;
if (requestToken !== bootstrapHydrationToken) return;
if (appState.me.approval_status !== "approved" && appState.me.role !== "super_admin") {
appState.dashboard = null;
@@ -3013,7 +3017,6 @@ async function bootstrap() {
renderAll();
return;
}
const dashboard = await storyforgeFetch("/v2/me/dashboard");
if (requestToken !== bootstrapHydrationToken) return;
appState.dashboard = dashboard;
const preferredPlatform = getCurrentPlatformValue();

View File

@@ -643,6 +643,13 @@ test("bootstrap renders the workspace shell before heavy hydration completes", (
assert.match(hydration, /void loadPlatformAccount\(getAccountPlatform\(nextAccount\), nextAccountId\)/);
});
test("bootstrap fetches me and dashboard in parallel before entering the workspace shell", () => {
const bootstrap = extractBetween(APP, "async function bootstrap()", "async function markTrackingDigestRead()");
assert.match(bootstrap, /const \[me, dashboard\] = await Promise\.all\(\[\s*storyforgeFetch\("\/v2\/me"\),\s*storyforgeFetch\("\/v2\/me\/dashboard"\)\s*\]\);/);
assert.match(bootstrap, /appState\.me = me;/);
assert.match(bootstrap, /appState\.dashboard = dashboard;/);
});
test("bootstrap only loads live recorder runtime endpoints when the integration is reachable", () => {
const hydration = extractBetween(APP, "async function hydrateWorkbenchDataAfterBootstrap(", "async function bootstrap()");
assert.match(hydration, /const liveRecorderIntegration = integrationHealth\?\.live_recorder \|\| null/);