Skip to content

Commit

Permalink
perf: improve images loading in carousel
Browse files Browse the repository at this point in the history
  • Loading branch information
MTG2000 committed Dec 28, 2023
1 parent dc78ed0 commit 63b6b1a
Showing 1 changed file with 32 additions and 21 deletions.
53 changes: 32 additions & 21 deletions v2/src/Components/ProjectsSelect/ProjectsSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"use client";
import React, { useEffect, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import { projects } from "./projects";
import { serifText } from "@/assets/fonts";
import Image from "next/image";
Expand All @@ -13,30 +13,14 @@ interface Props {
}

export default function ProjectsSelect({ excludeProjects }: Props) {
const [emblaRef, empblaApi] = useEmblaCarousel();
const [emblaRef] = useEmblaCarousel();
const router = useRouter();
const projectsContainerRef = useRef<HTMLUListElement>(null);
const isOnScreen = useOnScreen(projectsContainerRef);

const [openProject, setOpenProject] = useState<
(typeof projects)[number] | null
>(null);
const [slidesInView, setSlidesInView] = useState<number[]>([]);

useEffect(() => {
if (!empblaApi) return;

const updateNextSlidePriority = () => {
const slidesInView = empblaApi.slidesInView();
setSlidesInView(slidesInView);
};

empblaApi.on("init", updateNextSlidePriority);
empblaApi.on("slidesInView", updateNextSlidePriority);

return () => {
empblaApi.off("init", updateNextSlidePriority);
empblaApi.off("slidesInView", updateNextSlidePriority);
};
}, [empblaApi]);

const options = projects.filter(
(project) => !excludeProjects?.includes(project.slug)
Expand All @@ -59,7 +43,7 @@ export default function ProjectsSelect({ excludeProjects }: Props) {
return (
<LayoutGroup>
<div className="" ref={emblaRef}>
<ul className="flex gap-24">
<ul className="flex gap-24" ref={projectsContainerRef}>
{options.map((option, idx) => (
<motion.li
layout
Expand Down Expand Up @@ -103,6 +87,7 @@ export default function ProjectsSelect({ excludeProjects }: Props) {
alt=""
className="w-full my-42 shadow-2xl"
placeholder="blur"
priority={isOnScreen}
/>
</div>
</button>
Expand All @@ -126,3 +111,29 @@ export default function ProjectsSelect({ excludeProjects }: Props) {
</LayoutGroup>
);
}

function useOnScreen(
ref: React.MutableRefObject<Element | null>,
rootMargin = "0px"
) {
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
const elementToObserve = ref?.current;

if (!elementToObserve) return;

const observer = new IntersectionObserver(
([entry]) => setIsVisible(entry.isIntersecting),
{ rootMargin }
);
observer.observe(elementToObserve);

return () => {
if (!elementToObserve) return;

observer.unobserve(elementToObserve);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [rootMargin]);
return isVisible;
}

0 comments on commit 63b6b1a

Please sign in to comment.