From 7f07c111ac103db5464fd9ec67ab0f6733aa127c Mon Sep 17 00:00:00 2001 From: openhands Date: Sat, 3 Oct 2026 19:21:02 +0200 Subject: [PATCH] perf(studio): load motion's minimal entry instead of the full component library MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /admin/studio/furni sat at 94.9% of its initial-JS budget (427436 of 450560 gzip bytes), so the next feature would have broken the build. Of the 98228 gzip bytes unique to that route, a large part is framer-motion. This file uses motion twice, for one thing: a 150ms opacity fade on the result pane when viewMode changes. Importing `motion/react` to get it pulls in framer-motion's complete component library — 73 internal modules — plus its render components, drag/gesture and projection code, none of which is rendered here. `motion/react-m` ships only the element factories: 2 internal modules, and the same initial/animate/transition props, so the fade is unchanged. It exports the elements flat rather than under a `motion.` namespace, so the import becomes `div as Mdiv` and the two JSX tags are renamed to match. I could not measure the resulting bundle here: the local build is OOM-killed (exit 137) with the running containers on the host, so the actual saving is unverified. The CI build reports it in build-reports, and the number in this commit message should be read as a hypothesis, not a measurement. Verified: typecheck clean, lint clean, and the 10 studio UI tests pass — including the pane and navigation specs that exercise the view switch. --- src/components/admin/studio/studio-client.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/admin/studio/studio-client.tsx b/src/components/admin/studio/studio-client.tsx index 164b78be..db293b74 100644 --- a/src/components/admin/studio/studio-client.tsx +++ b/src/components/admin/studio/studio-client.tsx @@ -26,7 +26,13 @@ import { Trash2, X, } from "lucide-react"; -import { motion } from "motion/react"; +// motion/react-m is the minimal entry. The full motion/react pulls in +// framer-motion's entire component library (73 internal modules) for what this +// file needs: one fade-in on the result pane. The minimal entry ships only the +// element factories (2 modules) and exposes the same initial/animate/transition +// props, so the fade behaves identically. Only the element factory is +// imported, since that is the single one this file renders. +import { div as Mdiv } from "motion/react-m"; import { lazy, Suspense, @@ -2053,7 +2059,7 @@ export function StudioClient({

) : ( - )} - + )}