react 첫 화면 바로 보이기

정지훈·2022년 6월 25일
0

이미지 하나면 html에 다운 속도는 문제가 없는데 만약 이미지가 여러개면 유저가 페이지를 들어갈 때 바로 안보이고 다운로드가 완료된 이미지 먼저 보여준다.

하지만 이거는 사용자 경험에 안좋은 것이 되서 lazy loading을 시키면된다.

만약 백엔드에서 이미지를 받아올 때 img url을 img태그에 넣을 때

{
	imgItem ? <img src={imgItem}/> : <div>로딩중..</div>
}

이런식으로 만들었는데 이런건 이미지를 위한 lazy loading이 아니다. 그래서 검색을 하였는데

stackover flow에서 Promise.all() 이거를 이용하여 이미지를 캡쳐한다고 한다.

물론 js를 사용했을 때 이걸로 개발을 했었는데 js에서는 Promise all 을 사용하여 모두 다 true가 되었을 때 다운로드 된 걸 div children에 직접 img 태그를 동적으로 추가했는데
이 부분은 react에 가상 dom을 이용했을때 상당히 않 좋기 때문에 다른 방식을 찾아 봤다.

  const [imgsLoaded, setImgsLoaded] = useState(false);

useState를 하나 만든 후

  useEffect(() => {
    const loadImage = image => {
      return new Promise((resolve, reject) => {
        const loadImg = new Image()
        loadImg.src = image.url
        // wait 2 seconds to simulate loading time
        loadImg.onload = () =>
          setTimeout(() => {
            resolve(image.url)
          }, 2000)

        loadImg.onerror = err => reject(err)
      })
    }

    Promise.all(IMAGES.map(image => loadImage(image)))
      .then(() => setImgsLoaded(true))
      .catch(err => console.log("Failed to load images", err))
  }, [])

첫 페이지로 들어올때 IMAGES에 이미지를 loadImage에 넣어서 만약 load가 성공했을때 true 실패했을 때는 실패로그를 내보내서

  <>
      <main className="images">
        {imgsLoaded ? (
          IMAGES.map(image => (
            <img key={image.id} src={image.url} alt="Human" />
          ))
        ) : (
          <h1>Loading images...</h1>
        )}
      </main>
    </>

이렇게 넣어준다.

그래도 이미지 양이 몇 백개면 시간이 좀 걸릴 수 있지만 다 다운로드가 되었다면 한번에 다 보이기 때문에 사용자 경험쪽에선 보기에는 좋을 것이다.

참고 https://stackoverflow.com/questions/60847095/how-to-load-all-images-before-showing-the-page-in-react

0개의 댓글