[Perf] useVideoCleanup: Remove event listeners
This commit is contained in:
parent
9ad5cf4909
commit
af9d8695f4
@ -181,7 +181,8 @@ const VideoPlayer: FC<OwnProps> = ({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
useVideoCleanup(videoRef, []);
|
useVideoCleanup(videoRef, bufferingHandlers);
|
||||||
|
|
||||||
const [, setCurrentTime] = useCurrentTimeSignal();
|
const [, setCurrentTime] = useCurrentTimeSignal();
|
||||||
const [, setIsVideoWaiting] = useVideoWaitingSignal();
|
const [, setIsVideoWaiting] = useVideoWaitingSignal();
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,6 @@ function OptimizedVideo({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { handlePlaying: handlePlayingForAutoPause } = useVideoAutoPause(ref, canPlay, isPriority);
|
const { handlePlaying: handlePlayingForAutoPause } = useVideoAutoPause(ref, canPlay, isPriority);
|
||||||
useVideoCleanup(ref, []);
|
|
||||||
|
|
||||||
const isReadyRef = useRef(false);
|
const isReadyRef = useRef(false);
|
||||||
const handleReady = useLastCallback(() => {
|
const handleReady = useLastCallback(() => {
|
||||||
@ -77,6 +76,8 @@ function OptimizedVideo({
|
|||||||
return mergedHandlers;
|
return mergedHandlers;
|
||||||
}, [otherBufferingHandlers, restProps]);
|
}, [otherBufferingHandlers, restProps]);
|
||||||
|
|
||||||
|
useVideoCleanup(ref, mergedOtherBufferingHandlers);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
<video ref={ref} autoPlay {...restProps} {...mergedOtherBufferingHandlers} onPlaying={handlePlaying}>
|
<video ref={ref} autoPlay {...restProps} {...mergedOtherBufferingHandlers} onPlaying={handlePlaying}>
|
||||||
|
|||||||
@ -1,20 +1,31 @@
|
|||||||
import type { RefObject } from 'react';
|
import type { RefObject } from 'react';
|
||||||
import { onFullyIdle, useEffect } from '../lib/teact/teact';
|
import { resolveEventType } from '../lib/teact/dom-events';
|
||||||
|
import { onFullyIdle, useLayoutEffect } from '../lib/teact/teact';
|
||||||
|
|
||||||
import unloadVideo from '../util/browser/unloadVideo';
|
import unloadVideo from '../util/browser/unloadVideo';
|
||||||
|
import { useStateRef } from './useStateRef';
|
||||||
|
|
||||||
// Fix for memory leak when unmounting video element
|
// Fix memory leak when unmounting video element
|
||||||
export default function useVideoCleanup(videoRef: RefObject<HTMLVideoElement>, dependencies: any[]) {
|
export default function useVideoCleanup(videoRef: RefObject<HTMLVideoElement>, handlers?: Record<string, AnyFunction>) {
|
||||||
useEffect(() => {
|
const handlersRef = useStateRef(handlers);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
const videoEl = videoRef.current;
|
const videoEl = videoRef.current;
|
||||||
if (!videoEl) return undefined;
|
if (!videoEl) return undefined;
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
// eslint-disable-next-line react-hooks-static-deps/exhaustive-deps
|
||||||
|
const handlers2 = handlersRef.current;
|
||||||
|
if (handlers2) {
|
||||||
|
Object.entries(handlers2).forEach(([key, value]) => {
|
||||||
|
videoEl.removeEventListener(resolveEventType(key, videoEl), value, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// It may be slow (specifically on iOS), so we postpone it after unmounting
|
// It may be slow (specifically on iOS), so we postpone it after unmounting
|
||||||
onFullyIdle(() => {
|
onFullyIdle(() => {
|
||||||
unloadVideo(videoEl);
|
unloadVideo(videoEl);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
// eslint-disable-next-line react-hooks-static-deps/exhaustive-deps
|
}, [handlersRef, videoRef]);
|
||||||
}, dependencies);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export function removeEventListener(element: Element, propName: string, handler:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveEventType(propName: string, element: Element) {
|
export function resolveEventType(propName: string, element: Element) {
|
||||||
const eventType = propName
|
const eventType = propName
|
||||||
.replace(/^on/, '')
|
.replace(/^on/, '')
|
||||||
.replace(/Capture$/, '').toLowerCase();
|
.replace(/Capture$/, '').toLowerCase();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user