Skip to content

perf(embed): code-split the embed players and upload tracker - #3004

Merged
richiemcilroy merged 7 commits into
CapSoftware:mainfrom
07rjain:split/embed-player-split
Oct 24, 2026
Merged

richiemcilroy merged 7 commits into
CapSoftware:mainfrom
07rjain:split/embed-player-split

Conversation

@07rjain

@07rjain 07rjain commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Split out of #2580 (embed player split).

EmbedVideo loads the MP4/HLS player and upload tracker through next/dynamic, and uses motion/react for its chrome. The upload tracker is client-only and active uploads start in the fetching state, matching the share-page pattern.

Delayed player behavior:

  • Pending-loader tests render the embed before either MP4 or HLS arrives, then resolve the loader and verify start-time seeking and play/pause chrome updates.
  • Metadata events are captured on the player container. A DOM observer also initializes newly mounted players whose metadata has already loaded, and inspects existing video markup during hydration without waiting for the player ref. The observer disconnects on unmount.
  • Start-time seeking remains once-only across later metadata events, so level switches do not undo a viewer's scrub.
  • Player.js can bind to existing video markup before its ref attaches. Mount tests verify remote seeking and listener cleanup with and without an attached ref.

The branch includes current main at 3614bdb692af7317c30c0ad7afaa496a6974c2eb, integrating 174 upstream commits without conflicts.

Validation: 66 tests passed across five suites: 35 embed playback/branding tests, 11 playback-speed tests, 16 oEmbed tests, two Player.js protocol tests and two receiver mount/cleanup tests. Both cached-metadata regressions and the missing-ref receiver case failed before their fixes and passed afterward. Repository bun run typecheck and scoped Biome checks passed. No production bundle-size measurement or full production build was run locally.

The displayed Greptile 4/5 score was produced on 0feae42ee; the pending-loader coverage finding has been addressed since then. Review of this head and maintainer approval for fork CI remain pending.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; the previous coverage finding is addressed and no new actionable defects were established.

Summary

This PR loads the embed's MP4/HLS players and upload tracker through next/dynamic, and switches its chrome to motion/react.

  • The embed loads its players and upload tracker only when they are needed.
  • Embed playback follows video elements that mount after the page.
  • Player.js can connect to an embed video before its ref attaches.

The previous and current heads have different merge bases with the target commit, so this review used the full PR diff. Tests, a production build, and browser captures were not run during this review.

Reviews (2) · Last reviewed commit: "fix(embed): initialize delayed players w..." · Reviewed by Greptile

@vercel

vercel Bot commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

@07rjain is attempting to deploy a commit to the Cap Software Inc Team on Vercel.

A member of the Team first needs to authorize it.

Comment on lines +201 to +203
beforeAll(async () => {
await Promise.all(dynamicImports);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Late loading goes untested

The new next/dynamic mock starts every loader immediately, and beforeAll waits for all of them before rendering. This skips the loading behavior introduced by this PR, so the tests cannot catch problems when a player arrives after EmbedVideo mounts. Keep a loader pending during at least one test, resolve it after rendering, and check that playback events still update the chrome.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/__tests__/unit/embed-video-playback-chrome.test.ts
Line: 201-203

Comment:
**Late loading goes untested**

The new `next/dynamic` mock starts every loader immediately, and `beforeAll` waits for all of them before rendering. This skips the loading behavior introduced by this PR, so the tests cannot catch problems when a player arrives after `EmbedVideo` mounts. Keep a loader pending during at least one test, resolve it after rendering, and check that playback events still update the chrome.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@richiemcilroy

Copy link
Copy Markdown
Member

Thanks @07rjain, this is a nice split. It matches what ShareVideo.tsx already does (dynamic players, ssr: false upload tracker, the fetching initial state), and moving the embed onto motion/react drops the extra framer-motion runtime from the embed bundle.

The only open item is Greptile's P2 on apps/web/__tests__/unit/embed-video-playback-chrome.test.ts:203 (the next/dynamic mock resolves every loader before rendering, so the late-load path isn't exercised). It's a coverage point rather than a bug. With ssr left on and no loading option, next/dynamic doesn't add a Suspense boundary of its own, so the embed and its player hydrate together and videoRef is set before EmbedVideo's effects run (the startTime seek and usePlayerJsReceiver rely on that). Either add a small test that keeps one loader pending, resolves it after render and checks the chrome still reacts to playback events, or reply on Greptile's thread with that reasoning. Either is fine with us.

The branch is also quite far behind main now (it merges cleanly), so please merge main when you push so CI runs against current code.

It needs to reach Greptile 5/5 with green CI before we can merge. You can mention @greptileai in a comment to get a re-review after pushing. Thanks!

@greptile-apps

greptile-apps Bot commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Thanks — I agree the P2 is a coverage gap, not evidence that playback chrome is broken: the wrapper handles bubbled playback events, and the existing async-player case checks chrome after the video mounts. One caveat: ssr: true prerenders the player markup, but it does not guarantee the dynamic client module is hydrated before EmbedVideo’s effects run. If the player chunk resolves later, the startTime effect can see videoRef.current === null and return without retrying; unlike usePlayerJsReceiver, that effect does not wait for the player to appear. So a pending-loader test is reasonable, but the “they hydrate together” assumption doesn’t rule out that separate ref-timing case.

@vercel
vercel Bot temporarily deployed to Preview – cap-status October 23, 2026 23:37 Inactive
@vercel

vercel Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
cap-status Skipped Skipped Oct 24, 2026 9:52pm UTC

@vercel
vercel Bot temporarily deployed to Preview – cap-status October 23, 2026 23:56 Inactive
Observe mounted video elements so the start-time seek applies even when metadata loaded before the player ref attaches. Let Player.js bind to existing video markup during hydration and cover cached metadata, ref timing and receiver cleanup.
@vercel
vercel Bot temporarily deployed to Preview – cap-status October 24, 2026 09:09 Inactive
@07rjain

07rjain commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai please re-review the latest changes on commit 09ba832. The branch includes current main and pending-loader coverage for MP4/HLS playback, start-time seeking and chrome updates. The follow-up fixes also handle metadata already loaded before a delayed player mounts and Player.js binding before its video ref attaches, with cleanup coverage. Validation: all 66 focused tests, repository typecheck and scoped Biome pass. The displayed 4/5 review predates these changes.

@vercel
vercel Bot temporarily deployed to Preview – cap-status October 24, 2026 21:52 Inactive
@richiemcilroy
richiemcilroy merged commit f3a65cc into CapSoftware:main Oct 24, 2026
30 of 31 checks passed

This branch was previously deployed

1 inactive deployment
Preview – cap-status — b7c46d23 Deployed Oct 24, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants