Skip to content

[Bug]: Eliminate forced reflow during carousel initialization#1327

Open
dlabadini wants to merge 1 commit intodavidjerleke:masterfrom
dlabadini:bug/forced-reflow-on-init
Open

[Bug]: Eliminate forced reflow during carousel initialization#1327
dlabadini wants to merge 1 commit intodavidjerleke:masterfrom
dlabadini:bug/forced-reflow-on-init

Conversation

@dlabadini
Copy link
Copy Markdown

Problem

NodeHandler.getRects() unconditionally writes container.style.transform = 'none' before reading offsetWidth/offsetHeight, then restores it. This write-then-read pattern forces a synchronous browser reflow on every activate() call — even on initial mount when no transform has been applied yet (transform is '').

Additionally, activate() calls engine.translate.to() (which writes style.transform) before engine.resizeHandler.init() (which reads offsetWidth/offsetHeight), causing a second forced reflow per carousel init.

On pages with multiple carousels, these compound: each carousel init forces 2+ synchronous reflows, blocking the main thread during hydration.

Fix

getRects: Guard the transform write — only mutate style.transform when it's actually set to something other than 'none' or ''. On initial activate(), the transform is empty, so the guard skips the write entirely and the offsetWidth/offsetHeight reads don't force reflow.

activate: Move resizeHandler.init() and container.offsetParent (reads) before translate.to() and scrollOptimizer.optimize() (writes). Neither read depends on the translate position. This batches all layout reads before any layout writes.

Impact

  • Zero behavioral change — same dimensions, same snap points, same drag bounds
  • Eliminates forced reflow on initial carousel mount (the hot path)
  • On reActivate() after scrolling, the transform guard correctly fires when a transform is present

Verification

Chrome DevTools Performance panel before/after on a page with 9 Embla carousels:

  • Before: "Forced reflow while executing JavaScript" per carousel init, ~354ms Style & Layout
  • After: Clean — zero forced reflows from Embla, ~150ms Style & Layout

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant