Skip to content

Commit e77140a

Browse files
authored
perf(ui): drop typebox from Control UI startup by lazy-loading the approval page (#110528)
* perf(ui): drop typebox from Control UI startup by lazy-loading the approval page The approval document page was statically registered in app-host, pulling the protocol validators and the full typebox runtime (schemas, value checks, formats, locales) into every Control UI boot even though the page only renders for /approve document URLs. - register openclaw-approval-page through the existing OptionalCustomElement seam, preloaded only when bootstrap resolves an approval document mode; the approval document's booting splash covers the load gap - ratchet startup budgets to the new baseline (340 KiB gzip, 20 requests) so the win cannot silently regress Startup JS: 369.1 -> 321.8 KiB gzip (-13%), 22 -> 13 requests. * chore(ui): record approval-page label in i18n raw-copy baseline
1 parent 4d4099e commit e77140a

4 files changed

Lines changed: 21 additions & 3 deletions

File tree

scripts/check-control-ui-performance.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ const KIB = 1024;
1010
// Small, explicit headroom over the optimized baseline. Budget changes should
1111
// accompany an intentional loading or chunking decision.
1212
export const CONTROL_UI_PERFORMANCE_BUDGETS = Object.freeze({
13-
startupJsRequests: 28,
13+
startupJsRequests: 20,
1414
startupCssRequests: 1,
15-
startupJsGzipBytes: 370 * KIB,
15+
startupJsGzipBytes: 340 * KIB,
1616
startupCssGzipBytes: 42 * KIB,
1717
largestJsGzipBytes: 215 * KIB,
1818
largestCssGzipBytes: 42 * KIB,

ui/src/app/app-host.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ import { isTerminalAvailable } from "../lib/terminal-availability.ts";
5151
import { OpenClawLightDomElement } from "../lit/openclaw-element.ts";
5252
import { SubscriptionsController } from "../lit/subscriptions-controller.ts";
5353
import { findSettingsSearchBlocks } from "../pages/config/settings-search.ts";
54-
import "../pages/approval/approval-page-registration.ts";
5554
import { newSessionSearch, type NewSessionTarget } from "../pages/new-session/location.ts";
5655
import { renderDevicePairSetup } from "../pages/nodes/view-pairing.ts";
5756
import { pluginTabKey, pluginTabRefFromSearch } from "../pages/plugin/route.ts";
@@ -63,6 +62,7 @@ import {
6362
} from "./context.ts";
6463
import { resolveControlUiAuthToken } from "./control-ui-auth.ts";
6564
import {
65+
APPROVAL_PAGE_ELEMENT,
6666
BROWSER_PANEL_ELEMENT,
6767
COMMAND_PALETTE_ELEMENT,
6868
ensureOptionalElementForHost,
@@ -244,6 +244,9 @@ class OpenClawApp extends OpenClawLightDomElement {
244244
if (this.terminalOnly) {
245245
preloadOptionalElement(this, TERMINAL_PANEL_ELEMENT);
246246
}
247+
if (this.runtime.documentMode?.kind === "approval") {
248+
preloadOptionalElement(this, APPROVAL_PAGE_ELEMENT);
249+
}
247250
const context = this.runtime.context;
248251
this.initialAuthPresent = hasStoredGatewayAuth(context.gateway.connection);
249252
this.pendingGatewayUrl = this.runtime.pendingGatewayConnection?.gatewayUrl ?? null;

ui/src/app/lazy-custom-element.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ export const BROWSER_PANEL_ELEMENT = {
5656
loadModule: () => import("../components/browser/browser-panel.ts"),
5757
} satisfies OptionalCustomElement;
5858

59+
// Loaded only for approval document URLs: the approval page pulls the protocol
60+
// validators (typebox runtime) and must stay out of the normal startup graph.
61+
export const APPROVAL_PAGE_ELEMENT = {
62+
tagName: "openclaw-approval-page",
63+
label: "approval page",
64+
loadModule: () => import("../pages/approval/approval-page-registration.ts"),
65+
} satisfies OptionalCustomElement;
66+
5967
const hostElementLoads = new WeakMap<UpdatingHost, Map<string, Promise<void>>>();
6068

6169
export function isOptionalElementDefined(element: OptionalCustomElement): boolean {

ui/src/i18n/.i18n/raw-copy-baseline.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)