Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A way to avoid component re-mounts using <Sequence> #4201

Open
samohovets opened this issue Aug 15, 2024 · 0 comments
Open

A way to avoid component re-mounts using <Sequence> #4201

samohovets opened this issue Aug 15, 2024 · 0 comments

Comments

@samohovets
Copy link
Contributor

Feature Request 🛍️

A way to avoid component re-mounts using Sequence and Series components.

Use Case

At banger.show, users can add a lot of 3D objects like lights, models, boxes, and other objects to their videos.

The problems start when components like lights are remounted when the playhead enters or leaves their Sequence. This creates a noticeable lag even on the most powerful devices because the entire scene is recompiled.

Overall, even adding 10 3D models to the scene is already noticeable on weaker devices. Besides, it causes memory leaks.

Referring back to Three.js best practices, it's best not to remove objects completely, but to hide them. And that's what we're doing with now, but we'd like to do it with <Series.Sequence> too.

We are fixing this with our own modification but would like to have something built in as we want to rely less on internals and use the normal Remotion APIs 😃

❗️ I think this would be useful to all @remotion/three users!

Possible Solution

Internally, we use a user-land implementation that uses Remotion internals, AlwaysMountedSequence:

  // Original Sequence implementation above

  // Ceil to support floats
  // https://github.com/remotion-dev/remotion/issues/2958
  const endThreshold = Math.ceil(cumulatedFrom + from + durationInFrames - 1)

  const isVisible =
    absoluteFrame >= cumulatedFrom + from && absoluteFrame <= endThreshold

  const isSequenceHidden = hidden[id] ?? false

  if (isSequenceHidden) {
    return null
  }

  return (
    <SequenceContext.Provider value={contextValue}>
      {/* we're consuming this context in 3D objects and show or hide them */}
      <ContentVisibilityContext.Provider
        value={{
          visible: isVisible
        }}
      >
        {children}  {/* children is always mounted! */}
      </ContentVisibilityContext.Provider>
    </SequenceContext.Provider>
  )
}

/**
 * Banger.Show modification: a sequence that has always mounted children and provides the visibility state of the content.
 * to avoid re-mounting 3D objects or any other type of expensive components.
 */
export const AlwaysMountedSequence = forwardRef(
  AlwaysMountedSequenceRefForwardingFunction
)
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

No branches or pull requests

1 participant