Move the lifecycle labels out of the lazily loaded monitor page

The overlay is mounted from __root.tsx and imported two label helpers from the
page, so the page and its dependency graph were pulled into the eagerly loaded
bundle and the route's lazyRouteComponent bought nothing: every route paid for
the monitor page even when it was never opened. Measured on a production vite
build, the async api-monitor chunk was 0.20 kB, meaning the implementation had
landed in the main bundle.

The helpers now live in their own module. The same build gives an 18.83 kB
api-monitor chunk and a main bundle 18 kB smaller (3.9 kB gzipped).
This commit is contained in:
danielhanchen 2026-07-28 15:27:24 +00:00
commit 221b810d52
4 changed files with 66 additions and 35 deletions

View file

@ -24,7 +24,7 @@ import {
useRef,
useState,
} from "react";
import { isLifecycleEntry, lifecycleLabel } from "./api-monitor-page";
import { isLifecycleEntry, lifecycleLabel } from "./lifecycle";
import { useApiMonitorOverlayStore } from "./overlay-store";
import { computeStats } from "./use-api-monitor";

View file

@ -41,6 +41,7 @@ import {
import { HugeiconsIcon } from "@hugeicons/react";
import { type ReactElement, useEffect, useMemo, useRef, useState } from "react";
import { SavedModelSettingsPanel } from "./components/saved-model-settings";
import { isLifecycleEntry, lifecycleLabel } from "./lifecycle";
import {
type MonitorStatusFilter,
filterEntries,
@ -86,40 +87,6 @@ function compactEndpoint(endpoint: string): string {
.replace(V1_PREFIX_RE, "/");
}
// A lifecycle row is a model load/unload/download, not an HTTP call: it carries
// an event and reason instead of a prompt, so there is no payload to expand.
export function isLifecycleEntry(entry: ApiMonitorEntry): boolean {
return entry.kind === "lifecycle";
}
export function lifecycleLabel(entry: ApiMonitorEntry): string {
if (entry.event === "unload") {
return entry.reason === "idle" ? "Model unloaded (idle)" : "Model unloaded";
}
if (entry.event === "download") {
if (entry.status === "running") {
const pct = entry.progress;
return typeof pct === "number"
? `Downloading model (${Math.round(pct)}%)`
: "Downloading model";
}
if (entry.status === "completed") {
return "Model downloaded";
}
// A cancel is deliberate, so saying it failed misreads the user's own action.
return entry.status === "cancelled"
? "Model download cancelled"
: "Model download failed";
}
if (entry.status === "running") {
return "Loading model";
}
if (entry.status === "completed") {
return "Model loaded";
}
return "Model load failed";
}
function statusDotClass(status: ApiMonitorEntry["status"]): string {
switch (status) {
case "running":

View file

@ -0,0 +1,47 @@
// SPDX-License-Identifier: AGPL-3.0-only
// Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
// Labels for model load/unload/download rows, shared by the overlay and the
// full page.
//
// They live here rather than on the page because the overlay is mounted from
// __root.tsx, so importing them from the page would pull the whole page and its
// dependency graph into the eagerly loaded bundle and undo the route's
// lazyRouteComponent: every route would pay for the monitor page even when it
// is never opened.
import type { ApiMonitorEntry } from "@/features/chat/types/api";
// A lifecycle row is a model load/unload/download, not an HTTP call: it carries
// an event and reason instead of a prompt, so there is no payload to expand.
export function isLifecycleEntry(entry: ApiMonitorEntry): boolean {
return entry.kind === "lifecycle";
}
export function lifecycleLabel(entry: ApiMonitorEntry): string {
if (entry.event === "unload") {
return entry.reason === "idle" ? "Model unloaded (idle)" : "Model unloaded";
}
if (entry.event === "download") {
if (entry.status === "running") {
const pct = entry.progress;
return typeof pct === "number"
? `Downloading model (${Math.round(pct)}%)`
: "Downloading model";
}
if (entry.status === "completed") {
return "Model downloaded";
}
// A cancel is deliberate, so saying it failed misreads the user's own action.
return entry.status === "cancelled"
? "Model download cancelled"
: "Model download failed";
}
if (entry.status === "running") {
return "Loading model";
}
if (entry.status === "completed") {
return "Model loaded";
}
return "Model load failed";
}

View file

@ -746,3 +746,20 @@ def test_backfill_includes_a_standalone_gguf_with_no_variant():
assert 'entry.modelId.toLowerCase().endsWith(".gguf")' in src
# Still excluded for safetensors, which auto-switch does not resolve.
assert "entry.ggufVariant != null ||" in src
def test_monitor_overlay_does_not_pull_in_the_lazy_page():
"""The overlay is mounted from __root.tsx, so a static import of the page
for two label helpers drags the whole 900-line page and its dependency
graph into the eagerly loaded bundle and undoes the route's
lazyRouteComponent. Measured: the async api-monitor chunk was 0.20 kB with
the page in the main bundle, and 18.83 kB after the helpers moved, with the
main bundle 18 kB smaller.
"""
overlay = _read("features/api-monitor/api-monitor-overlay.tsx")
assert 'from "./lifecycle"' in overlay
assert "api-monitor-page" not in overlay, "the overlay must not reach the page"
# The helpers live in their own module, not re-exported through the page.
shared = _read("features/api-monitor/lifecycle.ts")
assert "export function isLifecycleEntry(" in shared
assert "export function lifecycleLabel(" in shared