Embla-carousel-react 图片加载缓慢
Embla-carousel-react slow image loading
我目前正在处理图像轮播,但图像加载存在一些问题。我的堆栈是:Next.js + embla。当我尝试滚动轮播时,前 2 个图像加载速度非常快,但第三个加载速度非常慢。这是我的代码:
/* eslint-disable jsx-a11y/control-has-associated-label */
import React, {
ReactElement,
useCallback,
useEffect,
useState,
MouseEventHandler,
} from 'react';
import { CarouselProps } from 'interfaces/components';
import Image from 'next/image';
import useEmblaCarousel from 'embla-carousel-react';
import clsx from 'clsx';
import styles from './carousel.module.scss';
const Carousel = (props: CarouselProps): ReactElement => {
const { images, hasShadow } = props;
const [emblaRef, embla] = useEmblaCarousel({ loop: true });
const [selectedIndex, setSelectedIndex] = useState(0);
const scrollPrev = useCallback(
(e) => {
e.preventDefault();
if (embla) embla.scrollPrev();
},
[embla]
);
const scrollNext = useCallback(
(e) => {
e.preventDefault();
if (embla) embla.scrollNext();
},
[embla]
);
const scrollTo = useCallback(
(e, index) => {
e.preventDefault();
if (embla) embla.scrollTo(index);
},
[embla]
);
const onSelect = useCallback(() => {
if (!embla) return;
setSelectedIndex(embla.selectedScrollSnap());
}, [embla, setSelectedIndex]);
useEffect(() => {
if (!embla) return;
onSelect();
embla.on('select', onSelect);
}, [embla, onSelect]);
const imagesOrPlaceholder =
images == null || images.length === 0
? ['/images/placeholder.jpg']
: images;
const NextButton = ({ onClick }: { onClick: MouseEventHandler }) => (
<button
className={[styles.arrow, styles.next].join(' ')}
onClick={onClick}
type="button"
>
<svg
xmlns="http://www.w3.org/2000/svg"
height="48px"
viewBox="0 0 24 24"
width="48px"
fill="#FFFFFF"
>
<path d="M9.29 15.88L13.17 12 9.29 8.12c-.39-.39-.39-1.02 0-1.41.39-.39 1.02-.39 1.41 0l4.59 4.59c.39.39.39 1.02 0 1.41L10.7 17.3c-.39.39-1.02.39-1.41 0-.38-.39-.39-1.03 0-1.42z" />
</svg>
</button>
);
const PrevButton = ({ onClick }: { onClick: MouseEventHandler }) => (
<button
className={[styles.arrow, styles.prev].join(' ')}
onClick={onClick}
type="button"
>
<svg
xmlns="http://www.w3.org/2000/svg"
height="48px"
viewBox="0 0 24 24"
width="48px"
fill="#FFFFFF"
>
<path d="M14.71 15.88L10.83 12l3.88-3.88c.39-.39.39-1.02 0-1.41-.39-.39-1.02-.39-1.41 0L8.71 11.3c-.39.39-.39 1.02 0 1.41l4.59 4.59c.39.39 1.02.39 1.41 0 .38-.39.39-1.03 0-1.42z" />
</svg>
</button>
);
return (
<div className={styles.embla} style={{ boxShadow: `${hasShadow ? "0px 4px 4px #AEA6A5" : ''}` }}>
<div className={styles.embla__viewport} ref={emblaRef}>
<div className={styles.embla__container}>
{imagesOrPlaceholder.map((img, idx) => (
<div className={styles.embla__slide} key={img}>
<div className={styles.embla__slide__inner}>
<Image
src={img}
layout="responsive"
width="100%"
height="125%"
objectFit="cover"
quality={100}
className={styles.featuredTileImage}
/>
</div>
</div>
))}
</div>
</div>
{imagesOrPlaceholder.length > 1 && (
<>
<PrevButton onClick={scrollPrev} />
<NextButton onClick={scrollNext} />
</>
)}
<div className={styles.dots}>
{imagesOrPlaceholder.length > 1 && imagesOrPlaceholder.map((_value, index) => (
<div className={styles.dotContainer} key={index}>
<div className={styles.dotAspect} />
<div
role="button"
onClick={(e) => scrollTo(e, index)}
onKeyDown={(e) => scrollTo(e, index)}
tabIndex={0}
className={clsx(
styles.dot,
selectedIndex === index && styles.active
)}
/>
</div>
))}
</div>
</div>
);
};
export default Carousel;
这是我的轮播
https://i.stack.imgur.com/SwaBB.png
也许这是来自 Next.js 的图像组件的一些问题?
问题与图像组件 lazy-loading 有关,已通过安装 sharp 包或作为图像的激进测量集预加载得到修复
我目前正在处理图像轮播,但图像加载存在一些问题。我的堆栈是:Next.js + embla。当我尝试滚动轮播时,前 2 个图像加载速度非常快,但第三个加载速度非常慢。这是我的代码:
/* eslint-disable jsx-a11y/control-has-associated-label */
import React, {
ReactElement,
useCallback,
useEffect,
useState,
MouseEventHandler,
} from 'react';
import { CarouselProps } from 'interfaces/components';
import Image from 'next/image';
import useEmblaCarousel from 'embla-carousel-react';
import clsx from 'clsx';
import styles from './carousel.module.scss';
const Carousel = (props: CarouselProps): ReactElement => {
const { images, hasShadow } = props;
const [emblaRef, embla] = useEmblaCarousel({ loop: true });
const [selectedIndex, setSelectedIndex] = useState(0);
const scrollPrev = useCallback(
(e) => {
e.preventDefault();
if (embla) embla.scrollPrev();
},
[embla]
);
const scrollNext = useCallback(
(e) => {
e.preventDefault();
if (embla) embla.scrollNext();
},
[embla]
);
const scrollTo = useCallback(
(e, index) => {
e.preventDefault();
if (embla) embla.scrollTo(index);
},
[embla]
);
const onSelect = useCallback(() => {
if (!embla) return;
setSelectedIndex(embla.selectedScrollSnap());
}, [embla, setSelectedIndex]);
useEffect(() => {
if (!embla) return;
onSelect();
embla.on('select', onSelect);
}, [embla, onSelect]);
const imagesOrPlaceholder =
images == null || images.length === 0
? ['/images/placeholder.jpg']
: images;
const NextButton = ({ onClick }: { onClick: MouseEventHandler }) => (
<button
className={[styles.arrow, styles.next].join(' ')}
onClick={onClick}
type="button"
>
<svg
xmlns="http://www.w3.org/2000/svg"
height="48px"
viewBox="0 0 24 24"
width="48px"
fill="#FFFFFF"
>
<path d="M9.29 15.88L13.17 12 9.29 8.12c-.39-.39-.39-1.02 0-1.41.39-.39 1.02-.39 1.41 0l4.59 4.59c.39.39.39 1.02 0 1.41L10.7 17.3c-.39.39-1.02.39-1.41 0-.38-.39-.39-1.03 0-1.42z" />
</svg>
</button>
);
const PrevButton = ({ onClick }: { onClick: MouseEventHandler }) => (
<button
className={[styles.arrow, styles.prev].join(' ')}
onClick={onClick}
type="button"
>
<svg
xmlns="http://www.w3.org/2000/svg"
height="48px"
viewBox="0 0 24 24"
width="48px"
fill="#FFFFFF"
>
<path d="M14.71 15.88L10.83 12l3.88-3.88c.39-.39.39-1.02 0-1.41-.39-.39-1.02-.39-1.41 0L8.71 11.3c-.39.39-.39 1.02 0 1.41l4.59 4.59c.39.39 1.02.39 1.41 0 .38-.39.39-1.03 0-1.42z" />
</svg>
</button>
);
return (
<div className={styles.embla} style={{ boxShadow: `${hasShadow ? "0px 4px 4px #AEA6A5" : ''}` }}>
<div className={styles.embla__viewport} ref={emblaRef}>
<div className={styles.embla__container}>
{imagesOrPlaceholder.map((img, idx) => (
<div className={styles.embla__slide} key={img}>
<div className={styles.embla__slide__inner}>
<Image
src={img}
layout="responsive"
width="100%"
height="125%"
objectFit="cover"
quality={100}
className={styles.featuredTileImage}
/>
</div>
</div>
))}
</div>
</div>
{imagesOrPlaceholder.length > 1 && (
<>
<PrevButton onClick={scrollPrev} />
<NextButton onClick={scrollNext} />
</>
)}
<div className={styles.dots}>
{imagesOrPlaceholder.length > 1 && imagesOrPlaceholder.map((_value, index) => (
<div className={styles.dotContainer} key={index}>
<div className={styles.dotAspect} />
<div
role="button"
onClick={(e) => scrollTo(e, index)}
onKeyDown={(e) => scrollTo(e, index)}
tabIndex={0}
className={clsx(
styles.dot,
selectedIndex === index && styles.active
)}
/>
</div>
))}
</div>
</div>
);
};
export default Carousel;
这是我的轮播
https://i.stack.imgur.com/SwaBB.png
也许这是来自 Next.js 的图像组件的一些问题?
问题与图像组件 lazy-loading 有关,已通过安装 sharp 包或作为图像的激进测量集预加载得到修复