Repository navigation
perf(dashboard): Serve styles, fonts, and avatar as hashed static assets - #2757
Merged
Merged
Conversation
The page shell inlined the full Tailwind stylesheet (177 KB) into every no-store HTML response and loaded Inter and Outfit from Google Fonts through a render-blocking @import on two extra origins. The client build now bundles the stylesheet with self-hosted variable fonts into content-hashed files under /_junior/dashboard/assets. The shell links the stylesheet and preloads the Latin font files. The avatar in the header and transcript is now an 88x88 hashed WebP (3 KB instead of the 76 KB PNG). Core no longer copies tailwind.css into server output. Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
BYK
approved these changes
Nov 5, 2026
…-css # Conflicts: # packages/junior-dashboard/src/client/conversations/TranscriptMessageShell.tsx
BYK
enabled auto-merge (squash)
November 5, 2026 18:14
Contributor
|
20 screenshot changes — 20 changed · 0 added · 0 removed Review screenshots in Frameshift Show 12 more changed screenshots2 more changed screenshots in Frameshift. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The page shell had the full Tailwind stylesheet (177 KB raw / 28 KB gzip) inline in every
no-storeHTML response. It also loaded Inter and Outfit through a render-blocking Google Fonts@import, which needs two more origins. The header and transcript avatar was a 76 KB PNG that was not hashed.src/styles.css(self-hosted fontsource variable fonts +dist/tailwind.css) intostyles-[hash].css. The fonts are*-[hash].woff2files under/_junior/dashboard/assets, the same immutable prefix as the JS from perf(dashboard): Serve dashboard browser files as static assets #2725. Fonts keepfont-display: swap.size-11) hashed WebP: 3.2 KB. No PNG fallback, because every supported browser decodes WebP./_junior/dashboard/avatar.pngstays for older cached clients and the install icons.tailwind.cssinto server output. Nothing reads it now.Numbers (
/conversations, mock conversations, production build)modulepreloadlinksOn a cold load, the first-load figure goes up because the CSS (23 KB br) and the Latin fonts (48 + 32 KB) now come from our origin instead of Google. The browser fetched about the same font bytes from gstatic before. On every later load, all of that is cached as immutable, so the HTML is the only transfer: 24.8 KB → 2.3 KB br.
Not in this PR: merging small chunks
esbuild has no minimum chunk size and no manual chunk grouping. 37 of the 58 preloaded chunks are under 4 KB, and 19 are under 1 KB. In an experiment, rolldown 1.2.15 with default splitting gave 21 static imports instead of 58 and 419,654 B br instead of 473,724 B, with the route splitting from #2734/#2738 kept. That needs the client build moved from tsup to rolldown and checked at runtime, so it is a separate follow-up.
Screenshots (mock conversations, 1440×900, dark)
The screenshots should look the same. Fonts loaded before:
Inter 400/500/600/700, Outfit 500from Google. After:Inter Variable 100–900, Outfit Variable 100–900from the assets prefix.Header avatar at 4× zoom, PNG (left) and WebP (right):
Checks
pnpm test:e2e:dashboard(playwright, local chromium): 100 passedpnpm --filter @sentry/junior-dashboard test: 370 passed, 1 failed. The failure isdashboard-output.test.ts. It also fails on cleanmainin this sandbox: the nitro build reportsMISSING_EXPORT nitroIntegrationfrom a hoisted@sentry/server-utils@11.6.0. CI should run it.nitro-plugin-module.test.tsandapp-config.test.ts: 42 passedfile-length,dashboard-style,test-architecture,package:lint, and the pre-pushpnpm lint: passvia @BYK.
--
View Session in Sentry