perf(web): inline initial booking styles #121

Merged
eleith merged 1 commits from perf/inline-booking-critical-css into main 2026-11-02 23:32:04 +00:00
3 changed files with 41 additions and 1 deletions

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
---
'@when/web': patch
---
Raise the per-stylesheet inlining limit so booking and rescheduling include their initial styles in the HTML rather than waiting for a render-blocking CSS request. This applies across the app, trading larger HTML responses for fewer separate stylesheet requests; styles above the limit remain external.
+34
View File
@@ -0,0 +1,34 @@
import { expect, test } from './support/test.ts';
import { seedAppointment } from './support/seed.ts';
test.use({ javaScriptEnabled: false });
for (const viewport of [
{ name: 'mobile', width: 390, height: 844 },
{ name: 'desktop', width: 1280, height: 900 }
]) {
test(`booking and rescheduling have inline initial styles on ${viewport.name}`, async ({
page
}) => {
await page.setViewportSize(viewport);
// The first render must not depend on an external stylesheet or hydration.
await page.route('**/_app/immutable/assets/*.css', (route) => route.abort());
const appointment = await seedAppointment();
const paths = [
'/schedule/chat',
`/appointment/${appointment.id}/reschedule?token=${appointment.cancel_token}`
];
for (const path of paths) {
const response = await page.goto(path);
expect(response?.status()).toBe(200);
await expect(page.getByRole('heading', { name: 'Step 1 of 3: Pick a day' })).toBeVisible();
await expect(page.locator('head link[rel="stylesheet"]:not([disabled])')).toHaveCount(0);
await expect(page.locator('.card-stage')).toHaveCSS('display', 'flex');
await expect(page.locator('.page-banner')).toHaveCSS(
'display',
viewport.name === 'mobile' ? 'flex' : 'none'
);
}
});
}
+2 -1
View File
@@ -24,7 +24,8 @@ export default defineConfig(({ command }) => {
filename.split(/[/\\]/).includes('node_modules') ? undefined : true
},
adapter: adapter(),
inlineStyleThreshold: 10240,
// Include the booking wizard's CSS in the initial HTML, avoiding a blocking request.
inlineStyleThreshold: 32 * 1024,
csp: {
directives: {
'default-src': ['self'],