mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
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.
This commit is contained in:
@@ -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
|
||||
@@ -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} />
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { DemoScheduler } from './demo-scheduler'
|
||||
export { DemoScheduler, preloadCalEmbed } from './demo-scheduler'
|
||||
|
||||
Reference in New Issue
Block a user