Skip to content

Commit a2f868c

Browse files
authored
fix(demo): preload the Cal.com booking embed while the visitor fills the form (#5616)
* fix(demo): preload the Cal.com booking embed while the visitor fills the form The embed script, booker iframe, and its assets only started downloading after the visitor pressed Continue, so the calendar took several seconds to appear. Warm the whole path on first form focus via the embed's documented preload instruction (hidden ?preload=true iframe caches the booker assets) plus a preconnect to app.cal.com. Nothing Cal.com-related loads at initial page load, so Lighthouse/LCP are untouched. * fix(demo): retry embed warm-up on failure, preconnect only on first focus Reset the preload guard when embed.js fails to load so a later focus can retry, and move the app.cal.com preconnect from render into the focus-triggered preload path so initial page load makes zero Cal.com connections.
1 parent 0cc6ed6 commit a2f868c

3 files changed

Lines changed: 40 additions & 2 deletions

File tree

apps/sim/app/(landing)/demo/components/demo-booking/demo-booking.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,24 @@
33
import { type CSSProperties, useEffect, useRef, useState } from 'react'
44
import { chipBorderShadowRing, cn } from '@sim/emcn'
55
import dynamic from 'next/dynamic'
6+
import { preconnect } from 'react-dom'
67
import { DemoForm, type DemoLead } from '@/app/(landing)/demo/components/demo-form'
78

89
const importScheduler = () => import('@/app/(landing)/demo/components/demo-scheduler')
910

11+
/**
12+
* Warm the entire booking path while the visitor fills the form: preconnect to
13+
* app.cal.com, then load the scheduler chunk, Cal.com's embed.js, and the
14+
* booker iframe assets (via the embed's `preload` instruction). Fired on first
15+
* form focus so nothing Cal.com-related competes with initial page load — the
16+
* connection handshake overlaps the chunk import, and it all finishes long
17+
* before the visitor submits.
18+
*/
19+
function preloadScheduler() {
20+
preconnect('https://app.cal.com')
21+
return importScheduler().then((m) => m.preloadCalEmbed())
22+
}
23+
1024
/**
1125
* Lazy-loaded so the Cal.com embed never enters the initial landing bundle - it
1226
* loads only once a visitor reaches the booking step. `loading: () => null` (no
@@ -75,7 +89,7 @@ export function DemoBooking({ className }: DemoBookingProps) {
7589
<div
7690
className='w-full min-w-0 shrink-0'
7791
inert={showScheduler}
78-
onFocusCapture={() => void importScheduler()}
92+
onFocusCapture={() => void preloadScheduler()}
7993
>
8094
<div ref={formRef} className='p-6 max-sm:p-5'>
8195
<DemoForm onComplete={setLead} />

apps/sim/app/(landing)/demo/components/demo-scheduler/demo-scheduler.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,30 @@ interface DemoSchedulerProps {
1919
lead: DemoLead
2020
}
2121

22+
let calEmbedPreloaded = false
23+
24+
/**
25+
* Warm the Cal.com embed before the scheduler mounts. Loads `embed.js` and
26+
* issues the embed's `preload` instruction, which fetches the booker in a
27+
* hidden `?preload=true` iframe so its assets are already cached when the real
28+
* embed renders on submit. Without this, nothing Cal.com-related starts
29+
* downloading until the visitor presses Continue, which is why the calendar
30+
* used to take several seconds to appear. Idempotent — repeat calls no-op
31+
* while a warm-up is in flight or done, but a failed embed.js load resets the
32+
* flag so a later focus can retry.
33+
*/
34+
export function preloadCalEmbed(): void {
35+
if (calEmbedPreloaded) return
36+
calEmbedPreloaded = true
37+
getCalApi({ namespace: CAL_NAMESPACE })
38+
.then((cal) => {
39+
cal('preload', { calLink: CAL_LINK })
40+
})
41+
.catch(() => {
42+
calEmbedPreloaded = false
43+
})
44+
}
45+
2246
/**
2347
* Step 2 of the booking card - the Cal.com scheduler, prefilled from the form's
2448
* {@link DemoLead}. Rendered inside the card chrome owned by {@link DemoBooking}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export { DemoScheduler } from './demo-scheduler'
1+
export { DemoScheduler, preloadCalEmbed } from './demo-scheduler'

0 commit comments

Comments
 (0)