Thief of Wealth
article thumbnail

다라쓰에는 오래전부터 한가지 문제가 있었다.

 

새로 고침할때마다 image보다 alt가 먼저 보이고 있다.

바로, 새로고침해서 이미지를 로드할때 이미지가 로딩되기 전에 alt가 먼저 노출되는 것이었다.

이제 기능추가나 코드를 예쁘게하는 시점보다 사용자가 좀더 쾌적하게 서비스를 이용할 수 있도록 해야했기 때문에 많은 고민이 되었다.

 

이것때문에 SSR을 도입을 많이 고민헀다. SSR은 서버에서 렌더링할 요소들을 모두 적용해주기 때문이다.

 

하지만 데모데이까지 남은시간은 불과 1~2일.

next js도 안니고 쌩으로 SSR을 적용하기엔 시간이 부족하다고 판단했다.

버그가 터지면 그것도 큰일..

 

그래서 다른 방법을 리서치해보고 있었다.

 

그러다가 한 크루가 아이디어를 던져주셨다.

바로 인라인으로 BASE64 형식의 data url을 넣는것

 

이게 되나? 라는 생각으로 자바스크립트 코드에 바로 문자열로 넣어보았다.

근데 잘되었다.

 

그럼 이제 url-loader의 limit값을 대폭높여서 모든 이미지를 인라인으로 박으면 될듯하다 는 절대안된다.

 

왜냐하면 저게 다 번들파일의 용량과 관련이 있기 때문이다.

 

실제로 이미지 1개를 data uri로 넣었는데 번들을해서 3kb가 들어났다.

문제를 해결할 수 있지만, 번들 용량이 기하급수적으로 늘어날 가능성도 있고 url-loader의 번들 limit을 파일을 추가할때마다 변경해주는 것도 좀 아니라고 생각했다.

 

2번째 방법은 img의 onLoad 이벤트를 이용하는 것이다.

onLoad되면 isVisible 상태를 true로 바꿔주는 것이다.

 

이렇게하면 모든 이미지에 ui에 대한 상태가 의존적으로 들어가게 될것이다.

하지만, 잘동작헀다. 심지어 애니메이션도 넣을 수 있어서 UX면으로는 훨씬 훌륭하게 개선할 수 있다고 기대했다.

 

코드는 아주 간단하다.

const Alarm = ({ hasUnReadNotification = false, size = "SM", onClick, ...props }: Props) => {
  const [isImageLoaded, setIsImageLoaded] = useState(false); // 상태가 추가되었다.

  return (
    <Container size={size} onClick={onClick} {...props}>
      <Img
        src={PNG.ALARM}
        alt="notification"
        isImageLoaded={isImageLoaded} // styled-component에서 isImageLoaded 플래그에 따라 스타일을 바꾼다.
        onLoad={() => setIsImageLoaded(true)} // Load되면 true로 바꿔준다.
        hasUnReadNotification={hasUnReadNotification}
      />
      {hasUnReadNotification && <Dot />}
    </Container>
  );
};

 

 

개선 후

이제 CSR에서 이미지가 모두 로딩되었을떄 이미지를 바로 보여줄 수 있게 되었다. 👍

SSR은 시간날때 다시 한번 생각해 봐야지.

 

https://github.com/woowacourse-teams/2021-darass/pull/785

 

profile on loading

Loading...