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

Improve resize listener with the loadedmetadata event in DailyVideo #11

Closed
wants to merge 2 commits into from

Conversation

rileyjshaw
Copy link
Contributor

The current onResize callback may not fire on initial load. Since it relies on React’s render timing (using a combination of useEffect and requestAnimationFrame) instead of events on the video, the video stream may not be loaded in time for the initial handleResize() call.

React has built-in support for onResize and onLoadedMetadata on video elements. This commit ditches the custom resize listener defined in useEffect in favor of these supported properties.

The current `onResize` callback may not fire on initial load. Since it
relies on React’s render timing (using a combination of `useEffect` and
`requestAnimationFrame`) instead of events on the video, the video
stream may not be loaded in time for the initial `handleResize()` call.

React has built-in support for `onResize` and `onLoadedMetadata` on
`video` elements. This commit ditches the custom resize listener defined
in `useEffect` in favor of these supported properties.
@Regaddi
Copy link
Contributor

Regaddi commented Jan 11, 2023

Thank you, @rileyjshaw, for the PR!

While the change itself makes a lot of sense, and I'm supportive of doing this, it also requires the libraries' dependencies on react, react-dom and their according types to be updated as well. Specifically with this change we'd require users of daily-react to update to React 18, since onResize on <video> elements was only added in React 18 (as you probably know 😄).
This is possibly the original reasoning for going with the useEffect based approach.

I'm a little hesitant to apply this change now, because of the required dependency update for customers.

Have you considered alternative solutions to the issue you're facing or do you think onResize is pretty much the only solution?

@Regaddi Regaddi self-assigned this Jan 11, 2023
@rileyjshaw
Copy link
Contributor Author

I'm a little hesitant to apply this change now, because of the required dependency update for customers.

That makes sense! Listening for the loadedmetadata event was the important part of this PR, so I can go back to the useEffect approach and add a listener for that event. Does that sound good to you @Regaddi?

@Regaddi
Copy link
Contributor

Regaddi commented Jan 11, 2023

That sounds like a plan, @rileyjshaw 👍

This preserves support for React versions below v18.
@@ -167,13 +167,13 @@ export const DailyVideo = forwardRef<HTMLVideoElement, Props>(
if (!onResize || !video) return;

let frame: ReturnType<typeof requestAnimationFrame>;
const handleResize = () => {
if (!video) return;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe video would have always been defined at this point. Instead, I added another check for videoEl.current further down.


return () => video?.removeEventListener('resize', handleResize);
return () => {
if (frame) cancelAnimationFrame(frame);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I’m not sure why all of these request/cancelAnimationFrames are needed, but I assume it’s related to a weird video edge case that I don’t have context on (eg. a video loading in a background tab).

If these are only intended to reorder the React lifecycle, I think moving from a useEffect to a callback ref would let you delete these and simplify the code.

In any case, I think adding a cancelAnimationFrame here prevents a callback firing on an already unmounted component.

},
[onResize, videoTrack]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed videoTrack because I think the loadedmetadata and resize listeners should handle this without re-running the effect.

@Regaddi
Copy link
Contributor

Regaddi commented Feb 8, 2023

This change has been released with 0.7.2!
Thanks for your contribution, @rileyjshaw! 🙇

@Regaddi Regaddi closed this Feb 8, 2023
@rileyjshaw
Copy link
Contributor Author

Awesome, thanks for the shout-out!

@rileyjshaw rileyjshaw deleted the patch-2 branch February 8, 2023 14:20
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