From 11deb3bba668003fc27f1aa611377ca18c8e1f60 Mon Sep 17 00:00:00 2001 From: 134 Date: Mon, 27 Jul 2026 18:24:20 +0800 Subject: [PATCH] perf: streamline HiCAD startup --- deploy/nginx-hicad-zoo-ws.conf.template | 1 + playwright.helpers.config.ts | 1 + scripts/vendor-zoo-modeling-app.mjs | 31 ++++++++++++- .../routes/hicad-embedded-performance.test.ts | 43 +++++++++++++++++++ vendor/zoo-modeling-app/localization.ts | 1 + 5 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 tests/routes/hicad-embedded-performance.test.ts diff --git a/deploy/nginx-hicad-zoo-ws.conf.template b/deploy/nginx-hicad-zoo-ws.conf.template index 3106772db..a68500f8d 100644 --- a/deploy/nginx-hicad-zoo-ws.conf.template +++ b/deploy/nginx-hicad-zoo-ws.conf.template @@ -17,6 +17,7 @@ location ^~ /vendor/zoo-modeling-app/fonts/ { location = /vendor/zoo-modeling-app/kcl_wasm_lib_bg.wasm { root /var/www/ai-chatbot/public; try_files $uri =404; + gzip_static on; add_header Cache-Control "public, max-age=3600" always; } diff --git a/playwright.helpers.config.ts b/playwright.helpers.config.ts index 1c10d4ef4..f30d2518d 100644 --- a/playwright.helpers.config.ts +++ b/playwright.helpers.config.ts @@ -14,6 +14,7 @@ export default defineConfig({ /routes\/canvas-runtime-internal-endpoint\.test\.ts/, /routes\/model-classification\.test\.ts/, /routes\/clawd-request-lifecycle\.test\.ts/, + /routes\/hicad-embedded-performance\.test\.ts/, ], fullyParallel: true, forbidOnly: !!process.env.CI, diff --git a/scripts/vendor-zoo-modeling-app.mjs b/scripts/vendor-zoo-modeling-app.mjs index 871816cfe..391df5af4 100644 --- a/scripts/vendor-zoo-modeling-app.mjs +++ b/scripts/vendor-zoo-modeling-app.mjs @@ -140,6 +140,12 @@ function patchOfficialSource() { " Zoo Design Studio", " HiCAD" ); + replaceSource( + "index.html", + ' ', + ` + ` + ); replaceSource( "src/Router.tsx", " createBrowserRouter,\n createHashRouter,", @@ -225,6 +231,19 @@ function patchOfficialSource() { ` className="cursor-pointer"\n id="freeze-frame"`, ` className="absolute inset-0 h-full w-full cursor-pointer"\n id="freeze-frame"` ); + replaceSource( + "src/components/OpenedProject.tsx", + "import { getMlEphantProjectReloadBehavior } from '@src/components/openedProjectUtils'\n", + "import { getMlEphantProjectReloadBehavior } from '@src/components/openedProjectUtils'\nimport env from '@src/env'\n" + ); + replaceSource( + "src/components/OpenedProject.tsx", + ` const needsOnboarded = + !window.electron &&`, + ` const needsOnboarded = + env().VITE_ZOO_API_TOKEN !== '${proxyToken}' && + !window.electron &&` + ); replaceSource( "src/index.tsx", "import { markOnce } from '@src/lib/performance'\n", @@ -357,7 +376,7 @@ function ensureWasm() { function precompressVersionedAssets(assetsDir) { for (const entry of readdirSync(assetsDir, { withFileTypes: true })) { - if (!entry.isFile() || !/\.(?:css|js)$/.test(entry.name)) { + if (!entry.isFile() || !/\.(?:css|js|wasm)$/.test(entry.name)) { continue; } const assetPath = path.join(assetsDir, entry.name); @@ -365,6 +384,15 @@ function precompressVersionedAssets(assetsDir) { } } +function precompressRootWasm(buildDir) { + const wasmPath = path.join(buildDir, "kcl_wasm_lib_bg.wasm"); + if (!existsSync(wasmPath)) return; + writeFileSync( + `${wasmPath}.gz`, + gzipSync(readFileSync(wasmPath), { level: 9 }) + ); +} + async function main() { ensureOfficialSource(); ensureDependencies(); @@ -393,6 +421,7 @@ async function main() { throw new Error("Zoo Design Studio build did not produce index.html"); } precompressVersionedAssets(path.join(buildDir, "assets")); + precompressRootWasm(buildDir); cacheBustZooModelingAppAssets(buildDir); rmSync(outputDir, { force: true, recursive: true }); diff --git a/tests/routes/hicad-embedded-performance.test.ts b/tests/routes/hicad-embedded-performance.test.ts new file mode 100644 index 000000000..40e936a5f --- /dev/null +++ b/tests/routes/hicad-embedded-performance.test.ts @@ -0,0 +1,43 @@ +import { expect, test } from "@playwright/test"; +import fs from "node:fs"; +import path from "node:path"; + +const projectRoot = process.cwd(); + +test.describe("HiCAD embedded startup", () => { + test("suppresses the upstream onboarding chooser in embedded mode", () => { + const vendorScript = fs.readFileSync( + path.join(projectRoot, "scripts/vendor-zoo-modeling-app.mjs"), + "utf8" + ); + const localization = fs.readFileSync( + path.join(projectRoot, "vendor/zoo-modeling-app/localization.ts"), + "utf8" + ); + + expect(vendorScript).toMatch( + /env\(\)\.VITE_ZOO_API_TOKEN !== '\$\{proxyToken\}'/ + ); + expect(localization).toContain("[data-testid='onboarding-toast']"); + }); + + test("preloads and serves the CAD wasm using a precompressed asset", () => { + const vendorScript = fs.readFileSync( + path.join(projectRoot, "scripts/vendor-zoo-modeling-app.mjs"), + "utf8" + ); + const nginxTemplate = fs.readFileSync( + path.join(projectRoot, "deploy/nginx-hicad-zoo-ws.conf.template"), + "utf8" + ); + + expect(vendorScript).toContain( + 'rel="preload" href="./kcl_wasm_lib_bg.wasm"' + ); + expect(vendorScript).toContain("/\\.(?:css|js|wasm)$/"); + expect(vendorScript).toContain("precompressRootWasm(buildDir)"); + expect(nginxTemplate).toMatch( + /location = \/vendor\/zoo-modeling-app\/kcl_wasm_lib_bg\.wasm \{[\s\S]*?gzip_static on;/ + ); + }); +}); diff --git a/vendor/zoo-modeling-app/localization.ts b/vendor/zoo-modeling-app/localization.ts index 7d8782b22..37f02b274 100644 --- a/vendor/zoo-modeling-app/localization.ts +++ b/vendor/zoo-modeling-app/localization.ts @@ -199,6 +199,7 @@ export function installHiCadLocalization() { } html[data-hicad-embedded='true'] [data-testid='download-desktop-app'], html[data-hicad-embedded='true'] [data-testid='billing-remaining-bar'], + html[data-hicad-embedded='true'] [data-testid='onboarding-toast'], html[data-hicad-embedded='true'] [data-hicad-official-account-link] { display: none !important; }