Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,24 @@
import { type CSSProperties, useEffect, useRef, useState } from 'react'
import { chipBorderShadowRing, cn } from '@sim/emcn'
import dynamic from 'next/dynamic'
import { preconnect } from 'react-dom'
import { DemoForm, type DemoLead } from '@/app/(landing)/demo/components/demo-form'

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

/**
* Warm the entire booking path while the visitor fills the form: preconnect to
* app.cal.com, then load the scheduler chunk, Cal.com's embed.js, and the
* booker iframe assets (via the embed's `preload` instruction). Fired on first
* form focus so nothing Cal.com-related competes with initial page load — the
* connection handshake overlaps the chunk import, and it all finishes long
* before the visitor submits.
*/
function preloadScheduler() {
preconnect('https://app.cal.com')
return importScheduler().then((m) => m.preloadCalEmbed())
}

/**
* Lazy-loaded so the Cal.com embed never enters the initial landing bundle - it
* loads only once a visitor reaches the booking step. `loading: () => null` (no
Expand Down Expand Up @@ -75,7 +89,7 @@ export function DemoBooking({ className }: DemoBookingProps) {
<div
className='w-full min-w-0 shrink-0'
inert={showScheduler}
onFocusCapture={() => void importScheduler()}
onFocusCapture={() => void preloadScheduler()}
>
<div ref={formRef} className='p-6 max-sm:p-5'>
<DemoForm onComplete={setLead} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,30 @@ interface DemoSchedulerProps {
lead: DemoLead
}

let calEmbedPreloaded = false

/**
* Warm the Cal.com embed before the scheduler mounts. Loads `embed.js` and
* issues the embed's `preload` instruction, which fetches the booker in a
* hidden `?preload=true` iframe so its assets are already cached when the real
* embed renders on submit. Without this, nothing Cal.com-related starts
* downloading until the visitor presses Continue, which is why the calendar
* used to take several seconds to appear. Idempotent — repeat calls no-op
* while a warm-up is in flight or done, but a failed embed.js load resets the
* flag so a later focus can retry.
*/
export function preloadCalEmbed(): void {
if (calEmbedPreloaded) return
calEmbedPreloaded = true
getCalApi({ namespace: CAL_NAMESPACE })
.then((cal) => {
cal('preload', { calLink: CAL_LINK })
})
.catch(() => {
calEmbedPreloaded = false
})
}

/**
* Step 2 of the booking card - the Cal.com scheduler, prefilled from the form's
* {@link DemoLead}. Rendered inside the card chrome owned by {@link DemoBooking}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { DemoScheduler } from './demo-scheduler'
export { DemoScheduler, preloadCalEmbed } from './demo-scheduler'
Loading