🚫 문제 - 이미지를 다양한 방법으로 업로드 할 수 있고
👉 code는 open sandBox를 확인하면 볼수있습니다.
import {useRef, useState, useEffect} from 'react'
import * as React from 'react'
interface IProps {
src: string
lazyImage?: string
alt?: string
}
export default function Image({src, lazyImage, alt}: IProps) {
const imgRef = useRef<HTMLImageElement>(null)
const [isLoad, setIsLoad] = useState(false)
useEffect(() => {
function loadImage() {
setIsLoad(true)
}
const imgEl = imgRef.current
imgEl && imgEl.addEventListener(LOAD_IMG_EVENT_TYPE, loadImage)
return () => {
imgEl && imgEl.removeEventListener(LOAD_IMG_EVENT_TYPE, loadImage)
}
}, [src])
useEffect(() => {
if (!observer) {
observer = new IntersectionObserver(onIntersection, {
// 확인을 위해 이미지 절반이 나타날 때 로딩한다.
threshold: 0.5
})
}
imgRef.current && observer.observe(imgRef.current)
}, [src])
return (
<>{!!src && <img ref={imgRef} src={isLoad ? src : lazyImage || '로딩동안 보일 이미지'} alt={alt || '이미지'} />}</>
)
}
let observer: IntersectionObserver | null = null
const LOAD_IMG_EVENT_TYPE = 'loadImage'
function onIntersection(entries: IntersectionObserverEntry[], io: IntersectionObserver) {
entries.forEach((entry) => {
if (entry.isIntersecting) {
io.unobserve(entry.target)
entry.target.dispatchEvent(new CustomEvent(LOAD_IMG_EVENT_TYPE))
}
})
}
큰 사이즈 이미지를 가져와 보자
이미지 큰 사이트
정적 이미지라면 아래 사이트에서 데이터를 줄여서 넣어보자
이미지 작게 사이트
다른 이미지 loading 또는 데이터는 들어왔지만 paint가 늦고 useEffect로 데이터를 넣어주고있다면 useLayoutEffect를 사용해보자
hooks | 차이 |
---|---|
useEffect | 렌더링 후 layout과 paint “후"에 비동기적으로 실행된다 |
useLayoutEffect | 렌더링 후 layout과 paint “전"에 동기적으로 실행된다 |
수많은 최적화중에 가장 최적화를 하기 좋은 아이템인 이미지에 대해서 최적화를 해보았다.
최적화 뿐만 아니라 loading의 위치와 이미지가 보이기 전에 보이는 이미지에 대해서도 webp를 이용하여 진행을 해보았고
이미지 최적화에 대해서는 여러가지의 방법이 있다는것을 볼수 있었다.
정적 이미지와 동적 이미지(axios등의 데이터 이미지)들을 어떻게 보일지에 대해서는 UX적으로도 preImage는 매우
필수적이라 생각이 든다.