zhaohai666 opened a new pull request, #1545: URL: https://github.com/apache/rocketmq-dashboard/pull/1545
# PR: perf(web): cut first-paint payload and cache static assets **Branch:** `feature/studio-web-perf-fixes` (based on `upstream/rocketmq-studio` @ `24715633`) **Commit:** `11a6fd60` — pushed to `origin/feature/studio-web-perf-fixes` **PR create link:** https://github.com/zhaohai666/rocketmq-dashboard/pull/new/feature/studio-web-perf-fixes ## Summary Three small, low-risk changes that reduce the frontend first-paint payload and stop re-downloading the ~1.8 MB JS bundle on every page load: 1. **nginx: cache hashed static assets immutably** (`web/nginx.conf`) - `location /assets/` now sends `Cache-Control: public, max-age=31536000, immutable` with `expires 1y`. Hashed filenames are content-addressable, so repeat visits no longer re-download the bundle. - `location = /index.html` now sends `Cache-Control: no-cache` so a released build is picked up immediately instead of serving a stale shell. - Added a commented-out Brotli block: the stock `nginx:alpine` image has no brotli module; the directives are documented for images that ship `ngx_brotli`. 2. **vite: stop preloading the markdown chunk on first paint** (`web/vite.config.ts`) - Removed `manualChunks.markdown`. `react-markdown` / `remark-gfm` are only used by the lazily-loaded `/ai` page; pinning them as a manual chunk forced the entry HTML to preload them (158 KB / 48 KB gzip) on first paint. - Verified with a fresh production build: the entry now references only `index` + `antd` + `react` + CSS; the markdown payload moved into the async `/ai` chunk (174 KB, loaded on demand). First-paint gzip drops from ~555 KB to ~507 KB. - Kept `chunkSizeWarningLimit: 1400` with an updated comment explaining that the antd vendor chunk (1.3 MB / gzip ~420 KB) is shared by the shell and most routes, and is now mitigated by immutable caching. 3. **layout: memoize menu / breadcrumb / navigation index** (`web/src/layouts/MainLayout.tsx`) - Wrapped `menuItems` (25+ JSX-icon items), `breadcrumbMap`, `breadcrumbItems`, the instance-scoped match, and `navigationEntries` in `useMemo`, keyed on their actual dependencies (`t`, `location.pathname`, `navigate`). - Previously these were rebuilt on every render (search typing, theme toggle, route change), recreating the whole menu tree and icon elements each time. ## Verification - `npx tsc -b` — passes. - `npx vitest run` — full frontend suite passes (incl. `MainLayout.test.tsx`, `navigationSearch.test.ts`). - Fresh `vite build` — entry HTML now loads only `index` + `antd` + `react` + CSS; markdown moves to the async `/ai` chunk. ## Files changed ``` web/nginx.conf | 21 +++++++++++++++++++++ web/src/layouts/MainLayout.tsx | 41 ++++++++++++++++++++++------------- web/vite.config.ts | 6 +++++- 3 files changed, 55 insertions(+), 13 deletions(-) ``` ## Notes - Brotli is intentionally **not** enabled to avoid breaking the stock `nginx:alpine` deployment; the config documents how to turn it on when the image includes the module. - No behavior changes to routes, i18n, or state management. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
