perf: Add priority image loading for the first 10 visible cards in movie and video grids.

This commit is contained in:
kuekhaoyang
2025-11-24 17:06:33 +08:00
parent 1384de946c
commit 5c4023b05c
4 changed files with 23 additions and 16 deletions
+4 -2
View File
@@ -21,9 +21,10 @@ interface DoubanMovie {
interface MovieCardProps {
movie: DoubanMovie;
onMovieClick: (movie: DoubanMovie) => void;
priority?: boolean;
}
export const MovieCard = memo(function MovieCard({ movie, onMovieClick }: MovieCardProps) {
export const MovieCard = memo(function MovieCard({ movie, onMovieClick, priority = false }: MovieCardProps) {
return (
<Link
href={`/?q=${encodeURIComponent(movie.title)}`}
@@ -45,7 +46,8 @@ export const MovieCard = memo(function MovieCard({ movie, onMovieClick }: MovieC
fill
className="object-cover transition-transform duration-300 group-hover:scale-105 rounded-[var(--radius-2xl)]"
sizes="(max-width: 640px) 50vw, (max-width: 768px) 33vw, (max-width: 1024px) 25vw, 20vw"
loading="lazy"
loading={priority ? "eager" : "lazy"}
priority={priority}
unoptimized
referrerPolicy="no-referrer"
onError={(e) => {
+12 -11
View File
@@ -22,13 +22,13 @@ interface MovieGridProps {
loadMoreRef: React.RefObject<HTMLDivElement | null>;
}
export function MovieGrid({
movies,
loading,
export function MovieGrid({
movies,
loading,
hasMore,
onMovieClick,
prefetchRef,
loadMoreRef
onMovieClick,
prefetchRef,
loadMoreRef
}: MovieGridProps) {
if (movies.length === 0 && !loading) {
return <MovieGridEmpty />;
@@ -37,11 +37,12 @@ export function MovieGrid({
return (
<>
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4 md:gap-6">
{movies.map((movie) => (
<MovieCard
key={movie.id}
movie={movie}
onMovieClick={onMovieClick}
{movies.map((movie, index) => (
<MovieCard
key={movie.id}
movie={movie}
onMovieClick={onMovieClick}
priority={index < 10}
/>
))}
</div>
+5 -2
View File
@@ -17,6 +17,7 @@ interface VideoCardProps {
cardId: string;
isActive: boolean;
onCardClick: (e: React.MouseEvent, cardId: string, videoUrl: string) => void;
priority?: boolean;
}
export const VideoCard = memo<VideoCardProps>(({
@@ -24,7 +25,8 @@ export const VideoCard = memo<VideoCardProps>(({
videoUrl,
cardId,
isActive,
onCardClick
onCardClick,
priority = false
}) => {
return (
<div
@@ -60,7 +62,8 @@ export const VideoCard = memo<VideoCardProps>(({
fill
className="object-cover rounded-[var(--radius-2xl)]"
sizes="(max-width: 640px) 33vw, (max-width: 1024px) 20vw, 16vw"
loading="lazy"
loading={priority ? "eager" : "lazy"}
priority={priority}
unoptimized
referrerPolicy="no-referrer"
onError={(e) => {
+2 -1
View File
@@ -89,7 +89,7 @@ export const VideoGrid = memo(function VideoGrid({ videos, className = '' }: Vid
contentVisibility: 'auto',
}}
>
{visibleItems.map(({ video, videoUrl, cardId }) => {
{visibleItems.map(({ video, videoUrl, cardId }, index) => {
const isActive = activeCardId === cardId;
return (
@@ -100,6 +100,7 @@ export const VideoGrid = memo(function VideoGrid({ videos, className = '' }: Vid
cardId={cardId}
isActive={isActive}
onCardClick={handleCardClick}
priority={index < 10}
/>
);
})}