我制作了一个视频组件,它使用 React.Suspense 组件在加载视频时显示占位符。问题是我的印象是它根本不起作用。当我将网络设置为“慢速 3G”时,我会看到一个长长的白屏,当所有内容都加载完毕后,我会看到占位符一秒钟,然后是视频。
有谁有更好的方法吗?
import React, { Suspense } from "react";
import Image from "next/image";
type Props = {
src: string;
placeholder: string;
type: string;
};
type PlaceholderProps = {
placeholder: string;
};
const Placeholder = (props: PlaceholderProps) => {
const { placeholder } = props;
return (
<div className="w-full h-full">
<Image
src={placeholder}
layout="fill"
objectFit="cover"
placeholder="blur"
blurDataURL={placeholder}
/>
</div>
);
};
export default function Video(props: Props) {
const { src, type, placeholder } = props;
return (
<>
<Suspense fallback={<Placeholder placeholder={placeholder} />}>
<video
preload="metadata"
loop
autoPlay
muted
className={`w-full h-full object-cover`}
>
<source src={src} type={`video/${type}`} />
</video>
</Suspense>
</>
);
}
React 应用程序在浏览器中呈现有不同的阶段。
长白屏
浏览器需要从某些远程位置(例如服务器或 CDN)下载所有资源(HTML、CSS 和 JavaScript)。在这个阶段,这与 React 无关。
我看到占位符一秒钟,然后是视频。
加载 JavaScript 包后,浏览器将开始加载 React 应用程序,您将在其中看到占位符。
总的来说,我会说“慢3G”是相当慢。取决于您所在的位置,平均速度可能会更快。话虽这么说,为了让您的网站加载速度更快,您可以:
我知道这已经晚了,但我希望这仍然可以帮助遇到此问题的任何人。
此方法的主要问题:
<video>
内的 <Suspense>
,是视频不被视为“支持暂停的数据源”。 了解更多
我还尝试将我的
<Video>
组件转换为带有 'next/dynamic
' 的 LazyComponent,但是,这仍然不起作用。
这就是我解决这个问题的方法:CSS
基本上,我将
position:absolute;
添加到后备 <Image>
和 <Video>
中。换句话说,它们在 div 中占据相同的空间。
然后,视频的
z-index
应该比图像更高。这样,图像通常首先加载,这将成为视频仍在下载时的后备。视频加载后,它将在后备之上渲染 <Image>
。
这是我的代码:
video.module.css
.video {
position: absolute;
top: 0;
z-index: -50;
}
fallback.module.css
.image {
z-index: -100;
position: absolute;
top: 0;
}
页面.tsx
<Image
src='img.jpg'
alt='image alt'
priority
className={styles.image}
width={1920}
height={1080}
objectFit='contain'
/>
<video autoPlay loop muted className={styles.video}>
<source src={src} type='video/mp4' />
</video>
您只需确保
<Image>
和 <Video>
在 DOM 中具有相同的大小和位置。