Skip to content

Fix Hyperspeed partial options override and improve performance#882

Merged
DavidHDev merged 7 commits intoDavidHDev:mainfrom
PedroMarianoAlmeida:Hyperspeed-performance
Feb 14, 2026
Merged

Fix Hyperspeed partial options override and improve performance#882
DavidHDev merged 7 commits intoDavidHDev:mainfrom
PedroMarianoAlmeida:Hyperspeed-performance

Conversation

@PedroMarianoAlmeida
Copy link
Contributor

@PedroMarianoAlmeida PedroMarianoAlmeida commented Feb 13, 2026

Summary

  • Fix partial effectOptions override — Previously, passing a partial effectOptions prop (e.g. { fov: 120 }) would
    completely discard all other defaults. Defaults are now extracted to a module-level DEFAULT_EFFECT_OPTIONS constant and
    merged at runtime, so users can override individual options without losing the rest.
  • Fix shallow merge on nested colors object — The colors property is now deep-merged separately, so passing { colors: {
    roadColor: 0xff0000 } } only overrides roadColor while preserving all other color defaults.
  • Fix unnecessary re-renders (TS variants) — The useEffect dependency was mergedOptions, a new object created every
    render, causing the effect to re-run constantly. Now depends on the stable effectOptions prop reference.
  • Remove stray console.log — Removed a debug log left inside the render loop (this.options.isHyper).

Performance note

Extracting defaults to a module-level constant (DEFAULT_EFFECT_OPTIONS) avoids recreating the object on every render and
provides a stable reference for useEffect dependencies — but only when no custom prop is passed. When the consumer
passes an inline effectOptions object, it will still be a new reference on every parent re-render, causing the WebGL
scene to be destroyed and recreated. A usage tip was added to the docs reminding consumers to memoize their
effectOptions (via useMemo or a constant) to prevent this.

Bug fixes
Bug: Partial options ignored defaults
Before: <Hyperspeed effectOptions={{ fov: 120 }} /> lost all other defaults
After: All defaults preserved, only fov overridden
────────────────────────────────────────
Bug: Partial colors replaced entire object
Before: { colors: { roadColor: 0xff0000 } } wiped other colors
After: Only roadColor overridden, rest kept
────────────────────────────────────────
Bug: useEffect re-ran every render (TS)
Before: Dependency on mergedOptions (new object each render)
After: Dependency on effectOptions (stable ref)
────────────────────────────────────────
Bug: console.log in render loop
Before: Logged isHyper on every frame
After: Removed
Changed files

Note: A little related to issue #875 (comment), but does't adress this specific issue (it is an overall performance, but not a cleanup of WebGL contexts

Note 2: If you want, I can record a video running Profiler to see the performance boost

@DavidHDev
Copy link
Owner

Awesome thanks!

@DavidHDev DavidHDev merged commit 0f71b2c into DavidHDev:main Feb 14, 2026
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