From c4af728c0d2c891ef53eff999bd311c5b6d9682d Mon Sep 17 00:00:00 2001 From: rcourtman Date: Mon, 24 Aug 2026 09:02:21 +0100 Subject: [PATCH] Stop modulepreloading every lazy chunk at cold start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SRI plugin's default preloadDynamicChunks injected modulepreload links for all ~50 lazy chunks into the built index.html — 3.1MB raw (4.2MB decoded): every Settings panel, Alerts, Chat, AI Intelligence, all six platform pages, and both locale bundles fetched and compiled up front, defeating route-level code splitting exactly where it matters (slow devices, tab-evicted mobile browsers that cold start often). Disable dynamic-chunk preloading; the entry keeps its three static vendor preloads and dynamic-import integrity stays enforced through the generated import map integrity block (112 entries verified in the built output). Measured on a 4x-CPU-throttled mobile profile against the 50-node mock estate: cold-load long tasks 32s -> 18s, scripts fetched 99 -> 62, decoded JS 4.2MB -> 2.3MB. Contract-Neutral: build-output preload posture change: deployment-installability's dev-runtime orchestration proof files all run the unbuilt hot-dev runtime and cannot observe built index.html preloads; verified instead by direct built-output inspection (0 route-chunk preloads, 112 importmap integrity entries) and 4x-throttle before/after measurement; substantive contract clause ships in this same commit --- .../v6/internal/subsystems/deployment-installability.md | 6 ++++++ frontend-modern/vite.config.ts | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/release-control/v6/internal/subsystems/deployment-installability.md b/docs/release-control/v6/internal/subsystems/deployment-installability.md index eddfcaa8a..7c40835be 100644 --- a/docs/release-control/v6/internal/subsystems/deployment-installability.md +++ b/docs/release-control/v6/internal/subsystems/deployment-installability.md @@ -978,6 +978,12 @@ upgrade, update, release, or artifact-selection behavior. deterministic token authentication after setup, and may use the server setup API as a fallback only when the UI wizard fails to complete cleanly under the managed hot-dev runtime. + The built `index.html` must not modulepreload lazy route chunks: the SRI + plugin runs with `preloadDynamicChunks: false` so cold start fetches only the + entry and its static vendor imports (route-level code splitting stays + effective on slow devices), while dynamic-import integrity remains enforced + through the generated import map `integrity` block. Reintroducing whole-app + preloading is a governed regression, not a tuning knob. Managed browser verification must also restart an existing hot-dev session when a verification lock is active or the runtime auth file no longer matches the deterministic dev user/hash. `tests/integration/scripts/run-playwright.mjs` diff --git a/frontend-modern/vite.config.ts b/frontend-modern/vite.config.ts index 44e1e5ccb..10b73710e 100644 --- a/frontend-modern/vite.config.ts +++ b/frontend-modern/vite.config.ts @@ -46,7 +46,11 @@ const proxyOriginOverride = process.env.PULSE_DEV_PROXY_ORIGIN ?? ''; const srcAlias = path.resolve(__dirname, './src'); export default defineConfig(({ mode }) => ({ - plugins: [solid(), sri({ algorithm: 'sha384' })], + // preloadDynamicChunks would modulepreload every lazy chunk (~3.1MB raw, + // the whole app incl. all Settings panels and every locale) at cold start, + // defeating route-level code splitting on slow devices. Dynamic-import SRI + // is still enforced through the generated import map integrity block. + plugins: [solid(), sri({ algorithm: 'sha384', preloadDynamicChunks: false })], resolve: { alias: { '@': srcAlias,