如何在 React Web 应用程序中重置 VIDEO & SOURCE DOM 内存组 (Firefox)

How to Reset VIDEO & SOURCE DOM Memory Groups in a React Web Application (Firefox)

提问人:Samuel Zrna 提问时间:9/20/2023 更新时间:10/1/2023 访问量:53

问:

我正在开发一个实时媒体播放器React应用程序,该应用程序可以在浏览器(尤其是Firefox)中交替显示全屏和元素。

我特别关心的是记忆。应用程序从不在窗口中重新加载,我看到每次播放视频后内存配置文件的大小都会跳跃,并且永远不会回落到基线。

您可以通过打开开发人员工具(f12)并打开“内存”选项卡,拍摄快照并切换到聚合视图来观察SOURCE和VIDEO内存组。

我尝试遵循此堆栈帖子中的解决方案,但无济于事。

我有一个沙盒示例和现场示例。

但要理解的主要两个组件是 和MediaPlayerVideoPlayer

媒体播放器:

import { useEffect, useState } from "react";
import "./MediaStyles.css";
import ImagePlayer from "./ImagePlayer";
import VideoPlayer from "./VideoPlayer";

const MediaPlayer = () => {
  const [mediaSwap, setMediaSwap] = useState<boolean>(false);

  useEffect(() => {
    const interval = setInterval(() => {
      setMediaSwap((swap: boolean) => !swap);
    }, 5000);
    return () => clearInterval(interval);
  }, [mediaSwap]);

  return (
    <>
      <div className="fullscreen-container">
        <div className="media-container">
          {mediaSwap ? <VideoPlayer /> : <ImagePlayer />}
        </div>
      </div>
    </>
  );
};

export default MediaPlayer;

视频播放器:

import { useEffect, useRef, useState } from "react";

const VideoPlayer = () => {
  const videoRef = useRef<HTMLVideoElement | null>(null);

  useEffect(() => {
    if (videoRef.current) {
      console.log("current mounted removal");
      videoRef.current.pause();
      videoRef.current.removeAttribute("src");
      videoRef.current.load();
    }

    return () => {
      if (videoRef.current) {
        console.log("current unmounted removal");
        videoRef.current.pause();
        videoRef.current.removeAttribute("src");
        videoRef.current.load();
      }
    };
  }, [videoRef.current]);

  return (
    <div>
      <video id="spotlight video" ref={videoRef} autoPlay muted playsInline>
        <source src="https://ibcdigitalsignageblob.blob.core.windows.net/fe3c4826-4e72-4cd4-a938-382d67a8badf/assets/2023-09-19_02_10_55_4kvid.mp4" />
      </video>
    </div>
  );
};

export default VideoPlayer;
reactjs typescript dom 内存 浏览器

评论


答:

0赞 Hisan 10/1/2023 #1

在 useEffect 清理函数运行时,ref 值可能已更改。复制到 useEffect 中的变量,并在清理函数中使用该变量。videoRef.currentvideoRef.current

src/VideoPlayer.tsx

const VideoPlayer = () => {
  const videoRef = useRef<HTMLVideoElement | null>(null);

  useEffect(() => {
    const videoRefCurrent = videoRef.current; // <--- Here

    if (videoRefCurrent) {
      console.log("current mounted removal");
      videoRefCurrent.pause();
      videoRefCurrent.removeAttribute("src");
      videoRefCurrent.load();
    }

    return () => {
      if (videoRefCurrent) {
        console.log("current unmounted removal");
        videoRefCurrent.pause();
        videoRefCurrent.removeAttribute("src");
        videoRefCurrent.load();
      }
    };
  }, []);

  return (
    <div>
      <video id="spotlight video" ref={videoRef} autoPlay muted playsInline>
        <source src="https://ibcdigitalsignageblob.blob.core.windows.net/fe3c4826-4e72-4cd4-a938-382d67a8badf/assets/2023-09-19_02_10_55_4kvid.mp4" />
      </video>
    </div>
  );
};