perf: streamline HiCAD startup

This commit is contained in:
134 2026-07-27 18:24:20 +08:00 committed by root
parent de8b7670b2
commit 11deb3bba6
5 changed files with 76 additions and 1 deletions

View File

@ -17,6 +17,7 @@ location ^~ /vendor/zoo-modeling-app/fonts/ {
location = /vendor/zoo-modeling-app/kcl_wasm_lib_bg.wasm { location = /vendor/zoo-modeling-app/kcl_wasm_lib_bg.wasm {
root /var/www/ai-chatbot/public; root /var/www/ai-chatbot/public;
try_files $uri =404; try_files $uri =404;
gzip_static on;
add_header Cache-Control "public, max-age=3600" always; add_header Cache-Control "public, max-age=3600" always;
} }

View File

@ -14,6 +14,7 @@ export default defineConfig({
/routes\/canvas-runtime-internal-endpoint\.test\.ts/, /routes\/canvas-runtime-internal-endpoint\.test\.ts/,
/routes\/model-classification\.test\.ts/, /routes\/model-classification\.test\.ts/,
/routes\/clawd-request-lifecycle\.test\.ts/, /routes\/clawd-request-lifecycle\.test\.ts/,
/routes\/hicad-embedded-performance\.test\.ts/,
], ],
fullyParallel: true, fullyParallel: true,
forbidOnly: !!process.env.CI, forbidOnly: !!process.env.CI,

View File

@ -140,6 +140,12 @@ function patchOfficialSource() {
" <title>Zoo Design Studio</title>", " <title>Zoo Design Studio</title>",
" <title>HiCAD</title>" " <title>HiCAD</title>"
); );
replaceSource(
"index.html",
' <meta name="theme-color" content="#000000" />',
` <meta name="theme-color" content="#000000" />
<link rel="preload" href="./kcl_wasm_lib_bg.wasm" as="fetch" type="application/wasm" crossorigin="use-credentials" />`
);
replaceSource( replaceSource(
"src/Router.tsx", "src/Router.tsx",
" createBrowserRouter,\n createHashRouter,", " createBrowserRouter,\n createHashRouter,",
@ -225,6 +231,19 @@ function patchOfficialSource() {
` className="cursor-pointer"\n id="freeze-frame"`, ` className="cursor-pointer"\n id="freeze-frame"`,
` className="absolute inset-0 h-full w-full 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( replaceSource(
"src/index.tsx", "src/index.tsx",
"import { markOnce } from '@src/lib/performance'\n", "import { markOnce } from '@src/lib/performance'\n",
@ -357,7 +376,7 @@ function ensureWasm() {
function precompressVersionedAssets(assetsDir) { function precompressVersionedAssets(assetsDir) {
for (const entry of readdirSync(assetsDir, { withFileTypes: true })) { 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; continue;
} }
const assetPath = path.join(assetsDir, entry.name); 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() { async function main() {
ensureOfficialSource(); ensureOfficialSource();
ensureDependencies(); ensureDependencies();
@ -393,6 +421,7 @@ async function main() {
throw new Error("Zoo Design Studio build did not produce index.html"); throw new Error("Zoo Design Studio build did not produce index.html");
} }
precompressVersionedAssets(path.join(buildDir, "assets")); precompressVersionedAssets(path.join(buildDir, "assets"));
precompressRootWasm(buildDir);
cacheBustZooModelingAppAssets(buildDir); cacheBustZooModelingAppAssets(buildDir);
rmSync(outputDir, { force: true, recursive: true }); rmSync(outputDir, { force: true, recursive: true });

View File

@ -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;/
);
});
});

View File

@ -199,6 +199,7 @@ export function installHiCadLocalization() {
} }
html[data-hicad-embedded='true'] [data-testid='download-desktop-app'], 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='billing-remaining-bar'],
html[data-hicad-embedded='true'] [data-testid='onboarding-toast'],
html[data-hicad-embedded='true'] [data-hicad-official-account-link] { html[data-hicad-embedded='true'] [data-hicad-official-account-link] {
display: none !important; display: none !important;
} }