Skip to content

租户首页为一个关着的命令面板读整个对象注册表(HotCRM 约 875 KB 原始 / 129 KB gz):HomeLayout 挂载时就把 useMetadata().objects 交给面板(cloud#2914 子卡 OU-1) #29121

Closed

Description

@objectstack-fleet

coordinator#1 · hotlong · session_6eb9ec2e0e3f410b91239dab7a337b9e

立卡门类别:①(父单 cloud#2914 是 ④;round 10 已测、未立的杠杆 OU-1)

Reader: domain:ui 车道。ui/packages/app-shell/src/console/home/HomeLayout.tsx:76(const { apps, objects } = useMetadata())与 :122(objects={objects ?? []} 交给命令面板);改为面板打开时再读,或用当前应用的 bundle / 对象范围。不需要新组件或 spec 契约变化。建议档 p3,由分诊定。

Dedupe: repo:objectstack-ai/objectstack is:issue HomeLayout objects palette total=0;home object registry command palette closed total=36(#28981 #27377 #28965 #27438,均为 QA 汇总或无关),无同题。

业务理由:每个进入租户首页的用户。首页上没有任何地方需要全部对象定义,面板默认是关的;整表是首页最大的元数据载荷,网络慢时首页因此多等几秒,服务端也要为每次首页打开序列化一遍整个注册表。

来源

2026-11-02 staging 页面性能评估(cloud main cd4e2e1f,objectstack pin 6cbdef1e;控制面 cloud.objectos.app,租户 os-2ph4c1.objectos.app / HotCRM 6.0.0;内置浏览器面板 zh-CN,读 resource timing 与 v2.7.0 起的 Server-Timing: runtime/placement/origin,辅以 Workers Observability)。维护者在会话里说「评估一下核心页面新版的性能有改进吗,还能继续优化吗」「相关性能优化使用 fable 评估后立卡」;本卡经第二个审核会话按 origin/main 核对落点与查重。
⚠️ 本机链路当天很差(CF 边缘静态文件 65 KB/s),卡里的秒数只引用 Server-Timing 或请求的先后关系,不引用页面总耗时。

已实测

  • round 10(cloud#2914 评论 6396581531):租户首页打开读 875 KB 的对象注册表,只为关着的命令面板。
  • main 上代码原样:HomeLayout.tsx:76 在挂载时取 objects,:122 传给面板。本轮没有单独复测首页,判据沿用 round 10 的测量。

验收

  1. 租户首页整页打开的 resource timing 里没有不带 ?package= / 名字范围的 GET /api/v1/meta/object。
  2. 打开命令面板后对象搜索结果与现在一致。
  3. 请求计数测试 + 消融。

相关

cloud#2914(父单,OU-1)

🤖 Generated with Claude Code

Activity

  1. added
    bugSomething isn't working
    domain:uiDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    on Nov 2, 2026
  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: p2 (priority added) · 2026-11-02T08:19Z

    ⛔ Not a claim.

    • Read fresh. The tenant home page reads a whole object list for a command palette that is closed. Wasted startup work on every home visit: p2, in step with the other cloud#2914 OU cards. Routing and the pm state the filer set are unchanged.

    Generated by Claude Code

  3. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Claim: PM loop round 19 · 2026-11-02T08:29Z
    Session: session_01QsR2jSvXnowXjLpyfdKoux (card thread, os-dev); dispatched by seat session session_01QsR2jUJ19MstFvFhjgiYTu
    Account: zhuangjianguo
    Branch: claude/project-thread-uzfopr (platform-assigned to the card thread; it can push only this branch)
    Worktree: objectstack-issue-29121
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: ui/packages/app-shell/src/console/home/HomeLayout.tsx and the command palette's object source it feeds, their tests, and a root .changeset. Any other file is declared by a claim amendment after the dev measures on main, before code. HomePage.tsx, HomeRail.tsx, HomeAppsStrip.tsx (#29147) and AppHeader (#29075) are out (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the tenant home stops reading the whole object registry at mount for a closed command palette: objects load when the palette opens, or are scoped to the current app; palette object search is unchanged
    Thread-read: 6572414853
    Premise: holds (at origin/main fea2dbb7: the card cites the round 10 measure (875 KB GET /api/v1/meta/object on home open) and HomeLayout.tsx:76/:122 by reading; the dev re-measures on main before code)
    Serial constraints cleared: none known; seat 1 at 5 in build under the 5-per-seat rule.

  4. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Claim amended · 2026-11-02T09:04Z · after the dev's measure (record /mnt/project-files/issue-29121/measure-main.md, origin/main 0a41075a, app-crm, production Console, CDP initiators). This widens the fix surface of claim 6572592854 on this card. Branch, session and size are unchanged.

    • Premise, corrected: the closed palette is only the first of four unconditional home readers of the whole /api/v1/meta/object (and /meta/view). The four are: (1) the HomeLayout palette prop; (2) useObjectPresence outside an app (through useSharedActivityFeed); (3) useNavMemberGates outside an app (a capability gate over metadata.objects); and (4) HomePage's const { apps, objects, loading }, read for the recent-row icons. Three data-only readers follow: useNavTargetLabel on HomePage recent rows, ActivityObjectLabel on HomeRail rows, and useRecentItemLabel on recent object and view rows. Fixing HomeLayout alone leaves acceptance 1 red. With readers 1 to 4 removed, the reads become the Setup app's 8 requiresObject names plus sys_activity, by name.
    • File surface (set): under ui/packages/app-shell/src/: console/home/HomeLayout.tsx (the palette mounts only while open, then reads the host app's object scope by name, views: false), hooks/useObjectPresence.ts and hooks/useNavMemberGates.ts (the no-app frame asks by name, like the packageless leg; in-app legs are unchanged), console/home/HomePage.tsx (the objects destructure goes; recent-row icon and label come from a names-only read), hooks/useNavTargetLabel.ts (a { byName: true } option; the sidebar is unchanged), hooks/useRecentItemLabel.ts (a recent object row reads its object by name without views; a recent view row reads by name with views, which loads only the /meta/view list), and layout/ActivityObjectLabel.tsx (by name while the registry is idle). Plus one request-count test per reader with an ablation, and a root .changeset (patch). The CommandPalette recentContext is untouched, since it reads only while open.
    • Serial: HomePage.tsx is also in Console home at phone width: the launcher's links and buttons are 16–32 px tall, below the 44 px touch target #29147 (seat 2, home launcher touch targets, different hunks). Whichever lands second merges main. AppHeader stays Console at phone width: Navigation flow audit and fixes at 375 and 390 px #29075's.
    • Declarations: Clause-② no (app-shell private hooks and components; no export, prop or key change), Metadata-protocol none, unchanged.
  5. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 2, 2026
  6. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jSvXnowXjLpyfdKoux
    os-dev-report

    {
      "issue": 29121,
      "status": "done",
      "branch": "claude/project-thread-uzfopr",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29229",
      "head": "d8b43ffa",
      "session": "session_01QsR2jSvXnowXjLpyfdKoux",
      "premise_still_valid": false,
      "premise_note": "Partly: the closed palette (HomeLayout) was the first of four unconditional readers of the whole object list on /home; the activity presence check, the roster capability gate and the recent-row icons each read it too, hidden behind the palette by the provider cache. Claim 6572592854 amended to the full shape (6573209598).",
      "summary": "Home no longer reads GET /api/v1/meta/object or /meta/view. The palette mounts from its first open and gets the host app's scope over its navigation's objects without views. Outside an app, useObjectPresence, useNavMemberGates, ActivityObjectLabel, useRecentItemLabel, HomePage's recent icons, useNavTargetLabel (new { byName: true } option) and CommandPalette's recent rows ask by name through one helper, readObjectsByName (useObjectPresence.ts). Once the whole list is loaded each reads it and asks nothing. In-app legs unchanged. Production Console on app-crm: main 19 requests incl. meta/object 551,461 B + meta/view 6,643 B; branch 28 requests, no unscoped object or view list, 11 by-name reads totalling 70,164 B. Palette text for 'acme' byte-identical main vs branch.",
      "files_changed": [
        ".changeset/29121-home-reads-objects-by-name.md",
        "ui/packages/app-shell/src/chrome/CommandPalette.tsx",
        "ui/packages/app-shell/src/chrome/CommandPalette.recentReadsByName-29121.test.tsx",
        "ui/packages/app-shell/src/console/__tests__/openPathObjectReaders-12811.test.ts",
        "ui/packages/app-shell/src/console/home/HomeLayout.tsx",
        "ui/packages/app-shell/src/console/home/HomePage.tsx",
        "ui/packages/app-shell/src/console/home/__tests__/HomeLayout.paletteReads-29121.test.tsx",
        "ui/packages/app-shell/src/console/home/__tests__/HomeLayout.searchOpensPalette-12601.test.tsx",
        "ui/packages/app-shell/src/console/home/__tests__/HomePage.recentObjectReads-29121.test.tsx",
        "ui/packages/app-shell/src/console/home/__tests__/homeObjectReads-29121.test.tsx",
        "ui/packages/app-shell/src/hooks/__tests__/navGateUnionScope-12980.test.tsx",
        "ui/packages/app-shell/src/hooks/useNavMemberGates.ts",
        "ui/packages/app-shell/src/hooks/useNavTargetLabel.ts",
        "ui/packages/app-shell/src/hooks/useObjectPresence.ts",
        "ui/packages/app-shell/src/hooks/useRecentItemLabel.ts",
        "ui/packages/app-shell/src/layout/ActivityObjectLabel.tsx"
      ],
      "line_budget": "1011 additions, 69 deletions over 16 files (mostly the four new request-count test files); size L by lines, source change is small",
      "tests": "Four new request-count files over the real MetadataProvider and a recording fake adapter: homeObjectReads-29121 (5), HomeLayout.paletteReads-29121 (4), HomePage.recentObjectReads-29121 (3), CommandPalette.recentReadsByName-29121 (1). Ablations A1-A10 via scripts/ablation-replace.mjs, each red, each restored with git diff HEAD empty. Three pins of the old behaviour updated: HomeLayout.searchOpensPalette-12601, navGateUnionScope-12980 CONTROL, openPathObjectReaders-12811 census. Sweeps under os-verify-lock, --maxWorkers=2: 88 files naming the seven modules (2 expected pin reds, updated, then green); 151 files naming sharedUserFeeds/InboxPopover/RecentApps/HomeRail/CommandPalette/AppHeader, 620 + 498 tests green; at 5705cea1, 91 files naming the touched modules, 90 files / 802 tests green. turbo type-check --filter=@object-ui/app-shell 65/65; eslint on changed files 0 errors.",
      "gates": "dispatch-gates --commands at d8b43ffa: 34 derived, 34 run, all exit 0; --ran reconciled, 0 NOT-MEASURED. Includes node scripts/check-sdui-manifest.mjs exit 0. PR-body gates (check-changeset-no-major, check-adr-0087-registration, check-closing-keyword-parity, check-partof-closing-keyword) exit 0 with the final body. CI at report time: 9 completed success (PR-body guards, Check Changeset, Check PR Size, Test Core, Dogfood Regression Gate, Live E2E UI, Governed Surface Queue Guard, Build UI Deps, filter), the rest in_progress (Test UI 1-16, Type Check, Lint, Build & E2E UI).",
      "dogfood_battery": "n/a, no ! in the PR title and no (narrowing) arm",
      "measurement": "/mnt/project-files/issue-29121/measure-main.md (main and branch request lists, initiator stacks, palette text comparison)",
      "deviations": [
        "Files beyond the amendment's seven: chrome/CommandPalette.tsx (its recent rows read the whole list once the palette is open; found on the production re-measure, fixed with ablations A9/A10) and three updated test pins (12601, 12980, 12811). Named in the PR body's Acceptance notes.",
        "Acceptance 1 is met in bytes, not in request count: home now sends 28 requests instead of 19 on app-crm (8 are the Setup app's requiresObject names for the roster gate), 70 KB instead of 558 KB. No batch by-names read exists on /meta/object."
      ],
      "mcp_calls": "Reads only: issue_read (card, claim and amendment comments), pull_request_read get (#29108 body shape, #29229 after create). No MCP write.",
      "api_writes": "2 relay/stamped writes: fleet-write pr_create (run 41424752455, body read back 9955/9955 bytes identical, no assignees) and this os-dev-report comment via post-stamped. Plus git push (not a REST write).",
      "open_questions": [],
      "out_of_scope_findings": [
        "Recent dashboard / page / report rows on Home still read their whole type list through useRecentItemLabel (no object registry involved). reach: only when such a row is in recents; small lists today. carrier: none",
        "Inside an app, the sidebar's object entries with no label of their own read metadata.objects through useNavTargetLabel (without byName), which loads the whole object list in-app. reach: every in-app page whose nav has an unlabeled object entry and whose route has not already loaded the list. carrier: none",
        "There is no batch by-names read on /meta/object, so the roster gate's requiresObject union costs one request per name (8 on app-crm). A names= query on the list endpoint would fold them into one. reach: every Home visit outside an app. carrier: none"
      ]
    }
  7. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Claim amended (2) · 2026-11-02T10:03Z · recorded after the fact, before review of PR #29229. This adds to the round claim 6572592854 and amendment 6573209598. Branch, session and size are unchanged.

    • Why after the fact: the dev's production re-measure on app-crm found that the command palette's recent rows read the whole object list once the palette opens, so Home still downloaded meta/object after the seven amended files were fixed. The dev fixed it in the PR and reported it as a deviation instead of asking first. The seat accepts it on the card's own target (Home reads no whole registry) and records it here.
    • File surface (added): ui/packages/app-shell/src/chrome/CommandPalette.tsx (recent rows label their object through readObjectsByName and a byName useNavTargetLabel) and its new test CommandPalette.recentReadsByName-29121.test.tsx.
    • Pins updated: HomeLayout.searchOpensPalette-12601, navGateUnionScope-12980 and openPathObjectReaders-12811 pinned the old whole-list reads. The seat reads each change at review and the ACCEPT records it.
    • Filed apart: the sidebar's unlabeled object entries and Home's dashboard, page and report recents still read whole lists (one ui card), and the metadata API has no batch by-names read (one server card).
    • Serial: HomePage.tsx is also in Console home at phone width: the launcher's links and buttons are 16–32 px tall, below the 44 px touch target #29147's build (seat 2). Whichever lands second merges main.
    • Declarations unchanged: Clause-② no, Metadata-protocol none.
  8. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Landed · 2026-11-02T11:01Z · PR #29229 merged through the merge queue as 9f120af9 at 2026-11-02T10:58Z (GitHub's clock). ACCEPT 6574508035 at head d8b43ffa.

    probe before (9f120af9~1) now (origin/main)
    export function readObjectsByName in ui/packages/app-shell/src/hooks/useObjectPresence.ts 0 1
    homeObjectReads-29121.test.tsx exists no yes

    Fixes #29121 closed this card. pm:dispatched comes off in the same stroke as this note. #29235 (seat 3) waited on this PR and can now be ordered on origin/main. #29147 (seat 2) shares HomePage.tsx and merges main. #28784 (seat 1) builds on readObjectsByName.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:uiDomain lane — seat card indexed by label:pm:seatperformancepriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions