오늘의 할 일 / scroll, Lazy-loading

lim1313·2021년 12월 13일
0

🍊 오늘의 할일

🍪 필수 Task

  • 마이페이지 비밀번호, 이메일 => oauth라면 수정되지 않도록 수정
  • 중복 신청 방지 error 핸들링 필요
  • 닉네임 중복 확인 처리 필요 (마이페이지 이메일, 닉네임)
  • 회원탈퇴 css 최소 넓이 조정 필요

🍊 오늘의 정리

🍉 Lazy loading / debounce

한번에 많은 이미지가 필요한 경우 lazy loading를 통해서 뷰포트에 보이는 이미지만을 로드하여 유저의 사용성을 높인다고 한다.

scroll 이벤트를 통해 이를 구현해 보았다.

  useEffect(() => {
    if (scrollTimeout) {
      scroller();
      ulRef.current.addEventListener('scroll', scroller, false);
    }
  }, []);

  const scroller = () => {
    const imgCard = cardRef.current;

    if (!imgCard) return;
    const classes = imgCard && imgCard.classList;

    if (classes.contains('imgload'))
      return ulRef.current.removeEventListener('scroll', scroller, false);
    let elementTop = cardRef.current.getBoundingClientRect().top;

    if (elementTop < window.innerHeight + window.pageYOffset + 500) {
      const node = cardRef.current;
      if (node) {
        classes.add('imgload');
      }
    }
  };

여기서 문제는 scroll이벤트가 매우 빈번하게 발생한다는 것이다. 이를 해결하기 위해 다양한 구글링을 하던 도중, throlle이라는 것을 알게되었다.

이러한 scroll이벤트를 사용할 때에는 throlle, debounce와 같은 기능과 함께 구현한다는 것 같다.

scroll 이벤트는 스크롤 시 여러 이벤트가 급격히 발생하므로, 약간의 쓰로틀 기능을 이용해서 lazy loading 기능을 적용하는 게 좋다.

아래와 같이 12개의 카드가 불려와 질 때 가장 아래의 카드까지 scroll한다면 157번의 이벤트가 발생한다.

이러한 빈번한 이벤트의 발생은 성능에 영향을 주기 때문에, scroll과 같은 이벤트의 경우 debounce 기능을 함께 사용한다.
간단하게 setTimeout으로 debounce기능을 구현하였다.

  let scrollerTimeStart;

  useEffect(() => {
    if (scroll) {
      scrollTimeout();
      ulRef.current.addEventListener('scroll', scrollTimeout, false);
    }
  }, []);

  const scrollTimeout = () => {
    if (scrollerTimeStart) {
      clearTimeout(scrollerTimeStart);
    }

    scrollerTimeStart = setTimeout(() => {
      const imgCard = cardRef.current;
      if (!imgCard) return;
      const classes = imgCard && imgCard.classList;

      if (classes.contains('imgload'))
        return ulRef.current.removeEventListener('scroll', scrollTimeout, false);

      let elementTop = cardRef.current.getBoundingClientRect().top;
      let elementLeft = cardRef.current.getBoundingClientRect().left;

      if (
        elementTop < window.innerHeight + window.pageYOffset + 500 &&
        elementLeft < window.innerWidth + window.pageXOffset + 500
      ) {
        const node = cardRef.current;

        if (node) classes.add('imgload');
      }
    }, 50);
  };

50ms의 setTimeout 비동기 처리를 해주었다.
또한 50ms 안에 동일한 scroll 이벤트가 발생하여 함수가 수행된다면 clearTimeout을 통해 불필요한 함수 실행을 멈춤으로써, 유저가 스크롤 이벤트를 어느정도 멈추었을 때 해당 함수가 실행되도록 하였다.

아래의 결과를 보면 이전보다는 조금 덜 scroll 이벤트가 발생하는 것을 확인할 수 있다.

🍉 Lazy loading 수정

Lazy loading과 관련된 자료를 정리하던 중 나의 구현사항에서 문제점을 인지하게 되었다.
해당 블로깅은 아래 링크를 통해 Go!

intersectionObserver을 통한 Lazy loading구현

🍉 userId PK

우리 팀은 user테이블의 userId를 pk로 설정했다.

그 이유는 다음과 같다.
1. userId는 고유한 값으로 관리할 것이다.
2. 그 때문에, 고유성의 성격을 갖는 pk로 설정하면 중복값을 걸러낼 수 있는 역할을 하기 때문에, pk의 성격을 활용하는 좋은 방법이다.

위와 같은 이유로 우리 팀은 처음부터 userId를 PK로 설정하여 진행했다.

하지만, 문제가 발생했고, 문제는 다음과 같다.
1. Oauth의 경우 userId를 따로 생성하지 않고, 기존 소셜 id를 가져와 사용한다.
2. 그 때문에, triplus 회원, 다른 oauth 가입자 간의 중복 userId가 생길 수 있다.

위와 같은 문제를 지금에서야 발견하게 되었다.

userId를 PK로 두어서는 안되는 것이다. Oauth를 사용하지 않고, 순수 회원가입자만 유저가 될 수 있다면, 중복값을 거를 수 있도록 PK로 사용해도 좋았을 것 같지만, Oauth 이용자가 있기 때문에, 별도의 index를 PK로 사용하고, userId는 일반 컬럼의 값으로 두는 편이 좋은 방법이었던 것 같다.

프로젝트의 마감이 4일 정도 남은 시점에서 db를 수정한다는 것은 무리가 있다고 판단하였고, 결국 백엔드에서 임의로 userId의 고유값을 생성하여 넣어주는 방식을 채택했다.
yy322342@kakao와 같은 방식으로 말이다.

하지만 여전히 다음과 같은 문제는 남아있다.
1. Oauth 유저가 회원탈퇴를 했을 때, 해당 동일 계정으로 회원가입을 할 수 없다는 것이다. userId가 PK이며 회원탈퇴 시 탈퇴한 회원을 user 테이블에서 제거하는 것이 아니라, expired_datetime의 column으로 관리하고 있어, 여전히 존재하는 userId이기 때문에, 이후 중복검사에서 에러가 발생하게 된다.

우리 웹의 특성상 userId로 활동하기보다는 nickname으로 활동하기 때문에, 더더욱 userId를 PK로 설정했던 것이 필수적이었나라는 의문이 들기도 햇다.

문제 해결(리뷰)

위의 1번 문제는 간단한 해결 방법은 다음과 같다.

현재 문제는 회원가입 시 중복되는 이메일인 경우 중복 검사로 재 회원가입이 불가능하다는 것이다.

이를 해결하기 위해서는
1. 회원가입 시 expired_datetime를 같이 검사해 주면된다.

즉, 이메일에서 중복이 된다면, 해단 이메일의 expired_datetime의 유무에 따라 탈퇴회원임을 확인하고, 재가입이 가능하도록 하면되는 것이다.


🍊 DevLog

🍉 구현이 되어서야 깨달은 점

오늘은 어떻게 프로젝트에 기여했나요?

  • 마이페이지 비밀번호, 이메일 수정 disable 추가
  • 가이드 카드 중복 신청 에러 핸들링
  • 마이페이지 이메일, 닉네임 수정 요청 시 중복에러 핸들링
  • 회원탈퇴 modal css 수정

오늘 프로젝트에서 힘들었던 점은 무엇인가요?

  1. 기획에서 확신했던 것들이 구현을 하면서 잘못되었음을 느끼게 되었던 점.

오늘 프로젝트에서 아쉬웠던 점은 무엇인가요?

  1. userId의 중복값을 제어하고 PK의 고유한 성격을 활용할 수 있도록 userId를 PK로 설정하였다. 하지만 Oauth의 구현 사항이 구체화되었을 때, userId의 중복값이 생길 수 있다는 것을 깨닫고, userId를 PK로 두는 것이 필수적이었나라는 의문이 들기도 햇다.

내일은 프로젝트에 기여하기 위해 무엇을 해야 하나요?

  • 지도 map 신청하기, 채팅하기 disable 추가 수정
  • mypage oauth 혹은 일반 유저에 따른 수정 가능 사항 에러 확인
profile
start coding

0개의 댓글

관련 채용 정보