Repository navigation
fix(producer): deduplicate scene font faces before embedding - #6395
Conversation
Preview approval requiredThis pull request comes from a fork, so Mintlify won't build a preview until someone with write access approves commit |
miguel-heygen
left a comment
There was a problem hiding this comment.
Thanks for picking this up, and for the careful write-up and size numbers on the issue. The approach looks right to me.
- Reusing
dedupeFontFaceRuleswith the same "always applied" filter the bundler uses (htmlCompiler.ts:945-952) keeps export consistent with preview. - Keeping the last copy matches how the browser resolves identical faces, and media, alternate and template styles plus nested rules are left alone.
- Running it before
embedLocalFontFacesmeans only paths get parsed, never font bytes.
I ran the local font embedding tests: 5/5 pass three times in a row. Each new test fails when I break the code: with the dedupe removed, with the filter widened to every style, and with a keep-first dedupe. Nice coverage.
Blocker
Buildis red atverify:packed-manifests: "@hyperframes/producer unpacked size 2869000 bytes is over its budget of 2840135 by more than 1%". The budget allows 1% over the last recorded size, and the added producer code pushes the bundle just past that limit. Build is green on the base commit and on main. Please raise@hyperframes/producer.unpackedinscripts/package-size-budgets.jsonand add a line to the PR body saying why. The verifier's own formula (size x 1.05) gives 3012450.Studio: edit accuracy gatefails only because its shards depend on Build and were skipped, so it should go green with the same fix.
Nits
htmlCompiler.ts:945-948: this repeats the bundler's privateisAlwaysAppliedStyle(packages/core/src/compiler/htmlBundler.ts:728-730). Exporting that function from core, rather thanUNCONDITIONAL_CSS_KEY, would keep one definition for preview and render.docs/guides/troubleshooting.mdx:218: one sentence telling readers what to do would help, for example that only identical declarations (same family,srcand descriptors) are merged, so a project that is still large should make its repeated scene font rules match exactly or declare them once in a shared root style.
Verdict: REQUEST_CHANGES
Reasoning: The code and tests look good, but this PR pushes the producer package over its size budget, which fails Build and with it the edit-accuracy gate. Raising the budget with a stated reason should be all that's needed.
|
Addressed in f37a6f7: the producer unpacked budget is now 3,012,450 bytes (the reported 2,869,000 × 1.05), with the reason added to the PR body. Preview and render share The 5 font-embedding tests and producer typecheck pass. The three core suites had 295 passes and 3 default-timeout failures; a targeted rerun of the affected groups passed all 4 tests with a 30-second timeout. Core/producer builds and the scoped lint, format, and comment checks pass. Full workspace/Studio edit-accuracy CI is left to the new head; the original project's end-to-end limitation still applies. Normal pre-commit checks passed, including core/studio/scripts typechecks and Fallow. The packed-manifest verifier could not run to completion locally because |
miguel-heygen
left a comment
There was a problem hiding this comment.
Thanks for the quick and thorough follow-up. All three earlier points are addressed:
- The producer unpacked budget is raised, and the PR body gives the reason.
isAlwaysAppliedStylenow lives in core (scriptRuns.ts:125) and is shared by the bundler and the render compiler.UNCONDITIONAL_CSS_KEYis private again.- The troubleshooting note now tells readers what to do.
I re-ran the local font embedding tests at this head: 5/5 pass three times in a row, and the producer typecheck is clean. Both new tests still fail when I break the code (filter widened to every style, dedupe removed).
One thing left before this can merge. The branch now conflicts with main, so none of the CI workflows ran on this commit. That includes Build, which is the check the budget change needs to clear. Two files conflict:
docs/guides/troubleshooting.mdxwas removed on main when Troubleshooting became a single page (#6380). The same section now lives indocs/help.mdx, under "The render looks different from preview" (around line 344). Please move the new "Repeated scene fonts make export HTML very large" subsection there.scripts/package-size-budgets.json: main has since raised the producer unpacked budget to 2897429. Keeping your 3012450 should be fine. If Build still complains after the rebase, use the size it reports.
Once it is rebased and CI is green, I'm happy to approve.
Verdict: REQUEST_CHANGES
Reasoning: Every earlier point is fixed and the tests hold up, but the branch conflicts with main (moved docs page, budget file), so CI never ran on this head and the size budget fix is unverified.
|
@Dante-dan thanks for this, it's the right fix. We confirmed it on current main: 92 scenes with 5 fonts go from 40.9 MB to 0.48 MB. To land it:
This one is blocking real exports, so if we don't see an update in the next hour or so we'll push the rebase onto your branch ourselves and keep your commits. |
The troubleshooting guide this section originally targeted was folded into docs/help.mdx on main, so the section now lives under the render troubleshooting entries there. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
f37a6f7 to
b50f05e
Compare
|
We've rebased this onto main for you, keeping your commits. The docs section moved to docs/help.mdx since the troubleshooting page was removed, and we dropped the size budget change since the package fits main's budget. Thanks for the fix! |
miguel-heygen
left a comment
There was a problem hiding this comment.
Re-reviewed exact head b50f05e5e9527911afaefd3c62574fe27932e0f8 against base 2be8bc2b9e8d6f9306a55b1c6af64c0049ce7c70.
The earlier blockers are resolved: the docs section is in docs/help.mdx:354, there is no package-budget delta, and current-head Build and Studio edit-accuracy runs succeeded. The merge tree with the captured base is clean. isAlwaysAppliedStyle is now shared by preview and render (scriptRuns.ts:125); the producer applies existing last-copy font deduplication before local-font embedding (htmlCompiler.ts:944-952,2184). Conditional/inactive styles retain their rules.
Executed: five producer local-font tests and 93 core compiler/style tests passed in an exact-source archive using existing dependencies. Removing deduplication makes the new order/size regression fail; widening the filter makes the conditional-style regression fail. Both mutations were restored and the five tests pass again. An independent synthetic 92-scene/five-local-font fixture produced 14,582,848 bytes / 460 faces with deduplication disabled versus 188,377 bytes / five faces at this head. This measures compiled HTML, not render speed or the original private project.
CI: snapshot has 80 successful checks, 45 skipped, one cancelled optional Studio/player capture and one neutral fork-preview approval. Successful Build 121669281358 and edit-accuracy 121680711684 are on this exact head; later duplicates are skipped. The single Build-log download attempt returned HTTP 503, so I am relying on GitHub's completed check result, not claiming a local package-size build or inspected successful log.
Scope/limits: inspected all six changed files, shared dedupe/filter implementation and render call ordering, prior review bodies/comments and consumer imports. Initial local collection needed the normal generated runtime artifacts and an existing jsdom dependency link; no installation was performed. No original-project export, first-frame/browser render, Linux Desktop timeout reproduction or hosted fork-docs preview was executed. This compiler-focused approval does not claim those acceptance results.
Verdict: APPROVE
Reasoning: The prior conflict/CI blockers are cleared at the captured head. Targeted tests, negative controls and the synthetic compile witness support the font-deduplication behavior without changing authored scenes or conditional styles.
— Magi
Merge 20 more upstream commits (acd0bc3..ad4d3fa, v0.8.205: heygen-com#6403, heygen-com#6363, heygen-com#6209, heygen-com#6395, heygen-com#6424, heygen-com#6426, heygen-com#6442, heygen-com#6430, heygen-com#6402, heygen-com#6435, heygen-com#6439, heygen-com#6449, heygen-com#5436, heygen-com#6455 and docs). No conflicts. Record the 11 open PRs heygen-com#6440-heygen-com#6458 and issue heygen-com#6443 in docs/DECISIONS.md (none adopted), re-check the earlier open PRs, and advance the commit watermark to ad4d3fa, the PR watermark to heygen-com#6458 and the issue watermark to heygen-com#6443. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
What
Deduplicate equivalent assembled
@font-facerules before the render compiler embeds local font data.Why
Repeating local font rules in scenes repeats their full data URIs in export HTML. This addresses the font expansion reported in #6381; I could not validate the original private project or the Linux Desktop navigation timeout end to end.
Related work
Fixes #6381. This follows the reporter's consolidation approach and reuses the existing core
dedupeFontFaceRulesoperation used bybundleToSingleHtml. #5098 addresses the separate ASCII-folding crash; #6134 bounds bundler asset expansion rather than deduplicating render font declarations. No overlapping implementation PR was found.How
Apply the shared deduplicator to active, unconditional assembled styles before coalescing and embedding. Keep the last equivalent declaration in its original position. Different descriptors, nested conditional rules, alternate/media styles and inert template styles remain intact. Source scene files are unchanged.
Test plan
font-variant-numericregression fixture compiles, then Chromium fails to launch with macOSMachPortRendezvous/bootstrap_check_in ... Permission denied (1100). No frames were captured,.Tested source is commit
439b5ff38ad305caa0157053e84add8b83a9e6ec. The long-running local pre-commit typecheck was interrupted and remains unverified; the already-passed Fallow audit and that unfinished hook were excluded when recording the signed commit.Review follow-up
Raised only
@hyperframes/producer.unpackedfrom 2,840,135 to 3,012,450 bytes as requested in review. Build measured 2,869,000 bytes for the producer package with the render deduplication code; 3,012,450 is that measured size × 1.05, following the verifier's headroom formula. The packed budget is unchanged.Preview and render now share
isAlwaysAppliedStylefrom core rather than duplicating its filter or exporting the CSS key. The troubleshooting section explains that declarations must match (family,src, and descriptors), and recommends matching repeated rules or a shared root style when export HTML remains large.Revision verification: the 5 local font-embedding tests pass; the three core suites returned 295 passed and 3 default-5-second timeouts, and the affected groups passed on a targeted rerun (4 passed) with a 30-second timeout. Producer typecheck, core/producer builds, lint, formatting, comment citations, and comment ratchet passed. Final pre-commit and packed-manifest results are recorded below. No end-to-end claim is made for the original private project or the Linux Desktop timeout.
Normal pre-commit checks passed, including core/studio/scripts typechecks and Fallow. The packed-manifest verifier could not run to completion locally because
pnpmwas unavailable (the local fallback executable returnedENOEXEC); the package-size/Studio gates still need remote CI verification.