Repository navigation
perf(workspace): load settings and secondary routes on demand - #6541
Conversation
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEADFor a same-repository clone whose Keep the DCO |
dc3f7b0 to
0ca064b
Compare
Every visit parsed one 1.59 MB chunk that included the settings editors, the contributor projection page, the benchmark study page and the answer report page, which most visits never open. Those become dynamic imports fetched the first time they are shown, each behind a visible loading status; the workspace route stays eager. First visit, as index.html loads it: JavaScript 1,592,902 → 1,364,480 bytes (gzip 456,653 → 396,717), CSS 374,647 → 360,276 bytes. Deferred: workspace-settings-page with its editors (204.8 kB), benchmark-study-page, frontstage-developer-page and answer-report-page. Codex team results stay eager: the loopx-mode scenario pins that their list loads exactly once when a configured team appears, and a lazy mount shifted that timing. The settings ternary keeps its structure, so the contract that the workspace stays mounted behind settings still holds; the contract test pins the boundaries and the loading state. The bundle manifest records every chunk and the one-upgrade asset retention already covers an old tab importing a deferred chunk; the upgrade smoke exercises it. Validation: dev scenarios capability-scope, steward-journey, goal-showcase, workspace-locale, loopx-mode; packaged build plus packaged capability-scope and goal-workspace-create; smoke:chat-upgrade; tests/presentation/test_chat_bundle.py; contract and theme tests; tsc; CSS token check; semantic inventory advisory. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: song <liusongstep@gmail.com>
0ca064b to
b669fb2
Compare
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max
精确头 b669fb25ffd660210e4d1b9be1fe071fe3cfa7e6;实际不可变 merge-base 3bc74f9317479e36286414d899a77172a115e330。
动机
打开工作区查看当前 Goal、偶尔再进入设置或次级页面的用户。原来一进工作区便下载设置和次级页代码;本提案先加载工作区,再在进入设置、开发者页、benchmark study 或答复报告时加载对应资源。正常打包的入口加 modulepreload JavaScript 从1619298降到1374407字节;页面与错误提示保持一致,延迟和失败资源也能通过现有加载提示和重新加载恢复。本 PR 不改变配置写入、权限、模型执行、资产保留策略或 Team 成果列表的加载时序。本地 premerge 缺少该基线与差异的质量收据,整体命令仍失败;未证明已安装 App 的采用、真实弱网延迟、托管费用或全部 CI 健康。
改动思路
继续使用 React.lazy、既有路由与设置条件入口,局部 Suspense 负责加载状态,原组件和错误恢复仍是 owner;无需新资源注册表、重试服务或第二套配置状态。当前 PR 交付可使用的按需加载切片;真实首屏时延与安装采用另行测量,缺失质量收据仍由原资格 owner 补齐,代码评审通过不解除合并资格。不改动时,普通用户查看当前Goal仍下载少用页面;把现有组件延迟到用户实际进入时,比自建资源缓存、加载注册表或重试服务更小。原设置字段、预览/应用与作用范围不变,用户无需新准备、复制或额外确认回合。第一次进入相关页可能多一次被动等待;真实加载失败使用原有Reload恢复,属于现有错误处理。
源码上的前后对照如下,是解释而非执行证明;没有另行渲染图。
| 入口 | 基线 | 当前头 |
|---|---|---|
| 工作区首页 | 同时加载设置及次级页 | 工作区先到 |
| 设置 | 已在初始包内 | 用户进入时加载,中文loading |
| 开发者/study/答复 | 已在初始包内 | 现有路由进入时加载,中英loading |
| Team成果列表 | eager | 继续eager,保留一次列表请求的时序 |
具体改动
独立依据 docs/development/frontend-delivery.md,spec_revision 3bc74f9317479e36286414d899a77172a115e330 的source build、PR资格和upgrade window,而非只接受本次新增Load boundaries段落。compiled-entry:implemented,正常源构建并操作实际编译产物;browser-required:implemented,通过真实页面对照与失败恢复;upgrade-window:implemented,原资产owner不变,现有真实HTTP/交付smoke在两头独立通过。该upgrade证据使用一次性最小版本模块,不声称完整安装升级后的Settings已验收。
完整5路径 +49/-9:router +15/-7、页面 +6/-2、loading CSS2行、contract14行、开发文档12行。没有新production模块、持久化schema、CLI/API、依赖或权限。现有route search parser和组件业务源码保持原样,输入合法性、数据作用域与写入仍属原owner。
关键代码讲解
FrontstageDeveloperPage/BenchmarkStudyPage/AnswerReportPage(router.tsx:17–19)把named export映射成lazy默认导出,各实际入口都有Suspense。/frontstage/developer原来就是Navigate至/developers/projections,独立执行该别名确认经过新wrapper;不能把重定向本身误当漏包裹的lazy组件。WorkspaceSettingsPage(page:89、2096)在原选择条件下加载,loading有role=status。原工作区保持mount,组件配置与状态归属没迁移。刻意保留GoalTeamResults直接import,避免将本轮优化扩展到一次性列表请求生命周期。Load boundaries(frontend-delivery.md:151)说明默认加载时机、Team例外、已有一代资产保留和public compiled验证;不是把机器必需资格改成建议,也没有新人工确认门槛。两行CSS仅使用既有token提供loading位置与颜色。
对主干的风险
最强反例是source contract正则通过,却因named export、router循环、旧alias或首次chunk失败而实际页面不可用。我正常构建实际base/head,在相同公共study夹具、合成保存答复和工作区输入下逐一打开开发者页、旧别名、study、正常答复、缺失答复、读取失败答复;六组完整可见文本逐字相同,候选实际请求了相应JS/CSS。缺失/失败仍给原“找不到这份答复”或“暂时无法读取”的明确状态,没有把异常转为成功。
设置页独立观察到首屏资源中没有Settings chunk;进入后对实际JS注入8秒延迟,显示可访问loading,随后实际“模型与执行器”出现。再使该JS一次503,原Page unavailable/Reload出现;点击Reload返回工作区后重新进入设置成功,alert为空。桌面和390px设置整屏已看过,标题、来源、字段与操作层级仍可读;未实际应用配置、调用模型或触碰活动Goal。合成会话创建/model-options读取沿用既有入口,0Turn/action/quota/validator。
同工具链实际正常构建,计入HTML直接module和所有modulepreload:JavaScript1619298→1374407字节,CSS382540→363818字节。不能只比较单个较小的index文件;共享router/chat仍首屏加载。四份构建并发,仅比较产物字节,不据构建时长推断真实弱网时延、CPU或托管费用。作者正文的旧基线数字与本次产物不同,本结论只使用上述可读回数值。
六项打包场景 capability-scope、steward-journey、goal-showcase、workspace-locale、loopx-mode、goal-workspace-create通过;正常构建/typecheck、workspace contract、CSS、独立全树semantic和18项chat-bundle测试通过(zip重复名负例保留一条warning)。原upgrade browser smoke分别在base/head使用真实HTTP与finish_delivery,证明A页在交付B后仍能迟加载A模块、交付C后按一代规则回收,不是mock retention helper。未把最小模块测试说成安装App已采用。
premerge3direct+11selected产品检查执行通过、0manual hold,但整体exit1/ok=false,quality_receipt_missing;当前精确base/diff的独立质量记录缺失,属于另外的资格状态。代码导入变化不生产该收据,本次没有伪造它。保留合并资格hold,不能说整体canary通过;不要求本PR改无关产品代码来调绿记录。diff/DCO通过,advisory先于全树semantic;未查询、派发或等待远程CI。
复用证据与当前头
发布前发现 rebase:旧头 0ca064bec3e5d15d6c1271223f150d2e19a96e29 → 当前 b669fb25ffd660210e4d1b9be1fe071fe3cfa7e6,新实际基线 3bc74f9317479e36286414d899a77172a115e330。range-diff确认提案补丁未变;基线带入既有Agent工作记录UI及可选workAgent搜索字段,不能把两头全部assets说成相同。逐一核对三个次级组件、Settings组件、main错误边界均为相同Git blob,lazy/Suspense段也未改。前述六组Ego文本、8秒/503/Reload及390px观察实际来自旧头,按这些边界失效检查复用;当前头重新正常构建、重跑六项打包集成(含设置/语言/权限)、18 bundle tests、全树semantic及base/head生产HTTP upgrade,并读回新入口总字节1619298→1374407。新基线Agent工作页不是本提案新增或本轮全面验收对象。 构建刷新依赖时我同时启动了CSS检查,先因postcss/postcss-value-parser暂时不可解析失败;构建全部完成后相同CSS命令分别通过,完整错误记录保留。未删除断言、改超时或改产品代码,整体premerge的质量收据失败仍未通过。
语义与 CI 对齐
这是明确披露的默认加载时序变化,不是可选能力开关,所以不存在凭空的feature-off证明。原输入、组件权限、配置生效来源与错误恢复未改;进入页面只获取代码不授予执行权。实际Settings拒绝/恢复和完整base/head文本,比只看import字符串更接近受影响用户任务。考虑过进一步抽公共loader或延迟Team;当前已有React边界足够,另加机制或触碰Team都会增加无关维护与回归面,因此不需要伴随重构。
我的整体评价
APPROVE,未发现当前差异的阻断性代码问题,作为 justified_increment:long_horizon improved,反复打开工作区不再预先下载这几块未用代码;user_experience preserved,同一任务无额外准备或授权回合,加载失败能沿现有路径恢复。继续使用 React.lazy、既有路由与设置条件入口,局部 Suspense 负责加载状态,原组件和错误恢复仍是 owner;无需新资源注册表、重试服务或第二套配置状态。当前 PR 交付可使用的按需加载切片;真实首屏时延与安装采用另行测量,缺失质量收据仍由原资格 owner 补齐,代码评审通过不解除合并资格。这不是整体CI健康、合并授权、安装升级采用或真实网络性能的证明;质量资格缺失必须继续显式处理,头变化后重新核验受影响路径。
English verdict: APPROVE - b669fb2. Normal compiled base/head preserve six secondary-route outcomes; actual Settings delay, chunk503, Reload and reopen succeed. Initial JS including all modulepreloads drops from1619298 to1374407 bytes. Focused product checks pass; overall premerge still fails missing exact-diff quality qualification. Installed adoption, real network timing, merge authority and full CI remain separate.
Summary
The chat bundle shipped as one 1.59 MB JavaScript chunk that every visit parsed in full, including the settings editors, the contributor projection page, and the benchmark study page that most visits never open. This introduces load boundaries with no behavior change: those surfaces become dynamic imports fetched the first time they are shown, each behind a visible loading status.
index.htmlloads)Deferred until first use:
workspace-settings-page(204.8 kB, gzip 61.2 kB, with its editors),benchmark-study-page(23.8 kB),frontstage-developer-page(14.0 kB) andanswer-report-page.What changed
router.tsx: the/developers/projections,/benchmarks/studyand answer-report routes useReact.lazywith aSuspensefallback; the workspace route stays eager.personal-workspace-page.tsx:WorkspaceSettingsPageis lazy with a loading fallback; the settings ternary keeps its existing structure (the contract test still pins that the workspace stays mounted behind settings). Codex team results stay eager on purpose: theloopx-modescenario pins that their list loads exactly once when a configured team appears, and a lazy mount shifted that timing in CI.personal-workspace-contract.test.mjspins the boundaries and that every lazy site shows a loading status.docs/development/frontend-delivery.mdgains a "Load boundaries" note so new secondary surfaces follow the same pattern.Why it is safe. The bundle manifest already records every delivered chunk, and the one-upgrade asset retention already covers an old tab importing a deferred chunk after a delivery; the upgrade smoke exercises exactly that. Behavior is unchanged: the same components render with the same props once their chunk arrives.
Validation
capability-scope(opens Settings),steward-journey,goal-showcase,workspace-locale,loopx-mode.chat_bundle.py build --install) then packaged scenarioscapability-scopeandgoal-workspace-create.smoke:chat-upgrade,tests/presentation/test_chat_bundle.py,personal-workspace-contract.test.mjs,workspace-theme.test.mjs, dashboardtsc --noEmit,check:css-custom-properties,generate_semantic_inventory.py --changed-from HEAD.Not covered. Installed App; a cold load over a slow link. The locale dictionaries (195 kB, both languages) remain eager; splitting them per locale is a possible follow-up with its own loading semantics.
Default change. None.
🤖 Generated with Claude Code