perf+a11y(agent-team): split vendor bundle + GPT-4.1 review fixes
GPT-4.1 cross-family review verdict: SHIP-WITH-FIXES, no BLOCKs (read-only, XSS-safe, no-backend, gate-vs-inert all confirmed). Applied: - a11y: aria-label on the Board/Pipeline Tabs; drawer collapsible section labels are now semantic <h3> headings. - Bundle: function-based rollup manualChunks splits react/flow/markdown/radix/ vendor so the 614 kB single chunk is gone (largest now ~142 kB react); app code drops to ~30 kB. Clears the 500 kB Vite warning. CSS splits too. (Skipped GPT's .prose-sm finding — incorrect; index.css uses a hand-written .md block, not Tailwind Typography. Roving-tabindex left out by design for this read-only view.) Typecheck + 36 tests + build all green.
This commit is contained in:
parent
751a6787f6
commit
3f4b95579e
3 changed files with 33 additions and 2 deletions
|
|
@ -127,6 +127,7 @@ export default function App() {
|
||||||
value={view}
|
value={view}
|
||||||
onValueChange={(v) => setView(v as View)}
|
onValueChange={(v) => setView(v as View)}
|
||||||
className="flex min-w-0 flex-1 flex-col"
|
className="flex min-w-0 flex-1 flex-col"
|
||||||
|
aria-label="Main view"
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-3 border-b border-border px-3 py-2">
|
<div className="flex items-center gap-3 border-b border-border px-3 py-2">
|
||||||
<TabsList>
|
<TabsList>
|
||||||
|
|
|
||||||
|
|
@ -264,9 +264,9 @@ function CollapsibleSection({
|
||||||
return (
|
return (
|
||||||
<Collapsible defaultOpen={defaultOpen}>
|
<Collapsible defaultOpen={defaultOpen}>
|
||||||
<CollapsibleTrigger className="flex items-center justify-between w-full group">
|
<CollapsibleTrigger className="flex items-center justify-between w-full group">
|
||||||
<span className="text-xs font-semibold text-muted-foreground uppercase tracking-wide">
|
<h3 className="m-0 text-xs font-semibold text-muted-foreground uppercase tracking-wide">
|
||||||
{title}
|
{title}
|
||||||
</span>
|
</h3>
|
||||||
<ChevronDown className="h-3.5 w-3.5 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
|
<ChevronDown className="h-3.5 w-3.5 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
|
||||||
</CollapsibleTrigger>
|
</CollapsibleTrigger>
|
||||||
<CollapsibleContent>
|
<CollapsibleContent>
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,36 @@ export default defineConfig({
|
||||||
outDir: "dist",
|
outDir: "dist",
|
||||||
emptyOutDir: true,
|
emptyOutDir: true,
|
||||||
sourcemap: false,
|
sourcemap: false,
|
||||||
|
rollupOptions: {
|
||||||
|
output: {
|
||||||
|
// Split heavy vendors into their own chunks so the app/UI code isn't
|
||||||
|
// re-downloaded when only a component changes, and to clear the 500 kB
|
||||||
|
// single-chunk warning. Function form (not object) so react-dom and
|
||||||
|
// transitive deps bucket precisely instead of collapsing into a stub.
|
||||||
|
manualChunks(id) {
|
||||||
|
if (!id.includes("node_modules")) return;
|
||||||
|
if (/[\\/]node_modules[\\/](react|react-dom|scheduler)[\\/]/.test(id))
|
||||||
|
return "react";
|
||||||
|
if (id.includes("reactflow") || id.includes("dagre")) return "flow";
|
||||||
|
if (id.includes("@radix-ui")) return "radix";
|
||||||
|
if (
|
||||||
|
id.includes("react-markdown") ||
|
||||||
|
id.includes("micromark") ||
|
||||||
|
id.includes("mdast") ||
|
||||||
|
id.includes("hast") ||
|
||||||
|
id.includes("unist") ||
|
||||||
|
id.includes("unified") ||
|
||||||
|
id.includes("remark") ||
|
||||||
|
id.includes("vfile") ||
|
||||||
|
id.includes("property-information") ||
|
||||||
|
id.includes("/decode-named-character-reference/") ||
|
||||||
|
id.includes("character-entities")
|
||||||
|
)
|
||||||
|
return "markdown";
|
||||||
|
return "vendor";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
proxy: {
|
proxy: {
|
||||||
|
|
|
||||||
Reference in a new issue