mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 17:27:09 +00:00
perf(studio): request the player chunk before the shell's first layout
The dynamic import of @hyperframes/player ran inside the preview's mount effect, which React schedules after the shell's first layout. On a cold open that layout stalls the main thread for seconds, so the chunk request waited behind it for no reason. The import is now kicked at module scope, behind a typeof window guard that preserves the documented SSR contract (the module registers a custom element at load), and the mount effect awaits the already-in-flight promise. Verified in the built bundle: the preload call sits at module top level, so the request goes out on bundle evaluation.
This commit is contained in:
@@ -5,8 +5,10 @@ import { useMountEffect } from "../../hooks/useMountEffect";
|
|||||||
import { applyPreviewVariablesToUrl } from "../../hooks/previewVariablesStore";
|
import { applyPreviewVariablesToUrl } from "../../hooks/previewVariablesStore";
|
||||||
import { HyperframesLoader } from "../../components/ui";
|
import { HyperframesLoader } from "../../components/ui";
|
||||||
// NOTE: importing "@hyperframes/player" registers a class extending HTMLElement
|
// NOTE: importing "@hyperframes/player" registers a class extending HTMLElement
|
||||||
// at module load, which throws under SSR. Defer the import to the mount effect
|
// at module load, which throws under SSR — hence the dynamic import behind a
|
||||||
// so it only runs in the browser.
|
// `typeof window` guard. Kicking it at module scope rather than in the mount
|
||||||
|
// effect puts the chunk request in flight before the shell's first layout.
|
||||||
|
const playerModule = typeof window === "undefined" ? null : import("@hyperframes/player");
|
||||||
|
|
||||||
interface PlayerProps {
|
interface PlayerProps {
|
||||||
projectId?: string;
|
projectId?: string;
|
||||||
@@ -166,8 +168,7 @@ export const Player = forwardRef<HTMLIFrameElement, PlayerProps>(
|
|||||||
let canceled = false;
|
let canceled = false;
|
||||||
let cleanup: (() => void) | undefined;
|
let cleanup: (() => void) | undefined;
|
||||||
|
|
||||||
// Dynamic import registers the custom element in the browser only.
|
playerModule?.then(() => {
|
||||||
import("@hyperframes/player").then(() => {
|
|
||||||
if (canceled) return;
|
if (canceled) return;
|
||||||
|
|
||||||
// Create the web component imperatively to avoid JSX custom-element typing.
|
// Create the web component imperatively to avoid JSX custom-element typing.
|
||||||
|
|||||||
Reference in New Issue
Block a user