Improve platform performance and user experience with optimizations
This commit enhances performance by optimizing video card previews, implementing memoization for categories, debouncing search queries, and enabling compression and caching strategies on the server. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 890577b1-c154-40a4-a177-a0c6d55320c3 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/890577b1-c154-40a4-a177-a0c6d55320c3/dCPgsyV
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState, useRef, useEffect } from "react";
|
||||
import { useState, useRef, useEffect, useMemo } from "react";
|
||||
import { useLocation } from "wouter";
|
||||
import { type Video } from "@shared/schema";
|
||||
import VideoCard from "./video-card";
|
||||
@@ -35,8 +35,8 @@ export default function NetflixGrid({ videos, isLoading }: NetflixGridProps) {
|
||||
setSelectedVideo(video);
|
||||
};
|
||||
|
||||
// Organize videos into categories
|
||||
const getCategories = (): VideoCategory[] => {
|
||||
// Memoize categories to avoid recalculation on every render
|
||||
const categories = useMemo((): VideoCategory[] => {
|
||||
if (!videos.length) return [];
|
||||
|
||||
// Sort by views for top content
|
||||
@@ -109,7 +109,7 @@ export default function NetflixGrid({ videos, isLoading }: NetflixGridProps) {
|
||||
videos: videos.slice(0, 12)
|
||||
}
|
||||
];
|
||||
};
|
||||
}, [videos]);
|
||||
|
||||
if (isLoading && videos.length === 0) {
|
||||
return (
|
||||
@@ -141,7 +141,7 @@ export default function NetflixGrid({ videos, isLoading }: NetflixGridProps) {
|
||||
);
|
||||
}
|
||||
|
||||
const categories = getCategories();
|
||||
// Categories are now memoized above
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -52,16 +52,16 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay
|
||||
const [currentTime, setCurrentTime] = useState(0);
|
||||
const [duration, setDuration] = useState(0);
|
||||
|
||||
// Delay preview start to avoid loading on quick mouse passes
|
||||
// Disable video preview for better performance - just keep hover effects
|
||||
useEffect(() => {
|
||||
if (isHovered) {
|
||||
// Only enable preview on desktop, disable on mobile
|
||||
if (window.innerWidth >= 768) {
|
||||
const delay = 800;
|
||||
hoverTimeoutRef.current = setTimeout(() => {
|
||||
setShowPreview(true);
|
||||
}, delay);
|
||||
}
|
||||
// Disable preview completely for performance
|
||||
// if (window.innerWidth >= 768) {
|
||||
// const delay = 800;
|
||||
// hoverTimeoutRef.current = setTimeout(() => {
|
||||
// setShowPreview(true);
|
||||
// }, delay);
|
||||
// }
|
||||
} else {
|
||||
if (hoverTimeoutRef.current) {
|
||||
clearTimeout(hoverTimeoutRef.current);
|
||||
@@ -136,7 +136,7 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay
|
||||
<img
|
||||
src={video.thumbnailUrl}
|
||||
alt={video.title}
|
||||
className={`w-full h-full object-cover transition-all duration-300 ${showPreview ? 'opacity-0' : 'opacity-100 group-hover:scale-105'}`}
|
||||
className="w-full h-full object-cover"
|
||||
style={{
|
||||
objectPosition: video.faceCenterPosition || 'center center',
|
||||
objectFit: 'cover'
|
||||
@@ -176,9 +176,9 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay
|
||||
playsInline
|
||||
controls={false}
|
||||
disablePictureInPicture
|
||||
onLoadStart={() => console.log('Preview loading for:', video.title)}
|
||||
onError={(e) => console.log('Preview failed for:', video.title)}
|
||||
onCanPlay={() => console.log('Preview ready for:', video.title)}
|
||||
onLoadStart={() => {}}
|
||||
onError={() => {}}
|
||||
onCanPlay={() => {}}
|
||||
onTimeUpdate={(e) => setCurrentTime(e.currentTarget.currentTime)}
|
||||
onLoadedMetadata={(e) => setDuration(e.currentTarget.duration)}
|
||||
onMouseMove={(e) => {
|
||||
|
||||
@@ -53,11 +53,15 @@ export default function Home() {
|
||||
}
|
||||
}, [videosResponse]);
|
||||
|
||||
// Only refetch when search changes
|
||||
// Debounce search to reduce API calls (500ms delay)
|
||||
useEffect(() => {
|
||||
if (searchQuery !== undefined) {
|
||||
refetch();
|
||||
}
|
||||
const debounceTimer = setTimeout(() => {
|
||||
if (searchQuery !== undefined) {
|
||||
refetch();
|
||||
}
|
||||
}, 500);
|
||||
|
||||
return () => clearTimeout(debounceTimer);
|
||||
}, [searchQuery, refetch]);
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user