[리팩토링] Swiper 리팩토링 - 문제점 도출

seeen·2024년 2월 28일
1
post-thumbnail

이번 편에서는 기존에 구현한 Swiper 컴포넌트 리팩토링을 위해 Swiper 컴포넌트가 가지고 있는 문제점에 대해서 분석해보는 내용에 대해서 다뤄보겠다.

문제점

대표적으로 다음과 같이 크게 세 가지의 문제점이 있다.

  • Tab Layout과 Swiper 컴포넌트 기능 혼합으로 인한 관심사 분리 미흡
  • Web API MatchMedia를 활용한 불안정한 반응형 로직
  • 불안정한 터치 스와이프 로직

최소한의 기능만을 놓고 보면 사용하는데는 불편함이 없지만, 몇 번 사용하다보면 어색함이 느껴지는 정도이다. 각 문제점을 자세히 알아보자.

관심사 분리 미흡

유저 입장에서는 문제가 없지만 추후 기능 추가, 수정 등 유지 보수 때나 Swiper를 사용하는 개발자 입장에서 약간의 복잡함이 있다. 대표적인 원인으로 Tab Layout 컴포넌트에서 확장되어 Swiper 컴포넌트를 구현한 것으로 볼 수 있겠다.

아래는 Swiper 컴포넌트가 받을 수 있는 Props 목록 중 일부이다.

$tabBoxHeight, $tabColor, $simpleTab 등 사용하지 않는 Tab Layout 컴포넌트를 위한 Props가 남아있는 것을 볼 수 있다. 이는 사용처에서 불필요한 Props를 지정해줘야하는 고민하는 과정이 필요할뿐만 아니라, Swiper 컴포넌트 내부의 구현 복잡도도 상승한다. 대표적으로 아래와 같은 JSX 내부에 조건문이 가독성을 떨어뜨린다.

{대충 조건문 && <Component />}

또한 Styled-Components를 활용하여 Swiper 컴포넌트를 구현했는데, 아래와 같이 Props에 따른 스타일링 로직을 달리하면서 이 또한 가독성이 떨어뜨렸다.

  // simpleTab 모드에서 원들이 가운데 정렬되므로 각 요소의 margin을 설정합니다.
  ${({ $simpleTab }) =>
    $simpleTab &&
    css`
      margin-right: 12px;

      &:last-of-type {
        margin-right: 0;
      }
    `}

    // simpleTab 모드가 아닐때, 포커스 된 탭 박스 하단 밑줄 구현부입니다.
    ${({ idx, pos, $focusColor }) =>
    idx === pos &&
    css`
      border-bottom: 2px solid ${$focusColor};
    `}

원래는 Tab Layout 형태로도 사용할 수 있겠다싶어 해당 기능들을 남겨두었지만, 프로젝트에 적용해본 결과 사용하지 않아 불필요한 기능으로 분리되었다.

다음으로 당연히(?) 적용해야할법한 기능을 기본값으로 지정해두었지만, 굳이 Props로 한 번 더 받아오는 점이다. 예를 들면 반응형 지원 여부, 모바일 사이즈에서 터치 스와이프 지원 여부인데 이 또한 각각 responsive, swipeable 이란 Boolean Props로 한 번 더 받아온다.

이런 Props 역시 JSX 또는 스타일링 로직에 불필요한 조건부를 한 번 두게 된다.

불안정한 반응형 로직

한 탭에 여러 개의 요소를 둔 경우 다음과 같이 브라우저 사이즈에 따라서 요소를 하나씩 다음 탭으로 미루는 과정이 필요하다.

이 로직은 Web API의 matchMedia를 활용해서 만들었는데 resize 이벤트가 발생할 때마다 콜백 함수를 실행하는 것이 성능적으로 좋진 않을 것이다. 그리고 코드를 분석하다보니 removeEventListener에 잘못된 콜백 함수를 넘겨주는 문제점도 있었다. 🫠

가장 큰 문제점은 따로 있었는데.. 바로 아래와 같다.

resize 이벤트로 media query 분기점에 도달했는지, 만약 도달했다면 요소를 하나씩 뒤로 미루도록 설계되어있는데 다음과 같이 resize 이벤트가 발생하지 않는 상황에선 반응형 로직이 동작하지 않는다. 태블릿, 모바일 환경에서는 브라우저 사이즈를 늘리고 줄일 일이 거의 없어 크게 문제되진 않았지만, PC에 경우 다소 치명적인 오류이다.

그리고 아래 사진처럼 밀려난 요소들로 인해 마지막 탭은 공백이 존재한다는 문제도 있다.

불안정한 터치 스와이프 로직

터치 스와이프 로직은 정말 간단하게 만들었는데 그림으로 보면 다음과 같다.

사진에서 diff 값은 스와이핑을 하는 가속도라고 보면 된다.

사진에서 diff의 값이 기준치보다 넘어가면 탭을 1개 증가 또는 감소하는 형태로 되어있다. 이 방식의 문제점은 아래와 같이 터치를 하는 순간부터 기준치에 도달하기 전 어떠한 반응도 없다는 점이다.

원래 일반적인(?) 방법으로 하면 diff의 값을 탭 width와 비교하여 탭이 움직이면서 일정 기준치 이상을 넘기면 그제서야 탭이 전환되는 방법으로 설계하는 것이 되겠다. 그리고 아래와 같이 터치를 유지한채로 좌우로 스와이핑하면 지속적으로 탭이 150ms 간격으로 전환되는 것 또한 확인해볼 수 있다. (150ms로 쓰로틀링을 걸어두었다.)

이처럼 실제 사용할 때는 스와이프가 문제 없는 것처럼 느껴지지만, 간혹 기준치에 도달하지 못한 스와이핑은 사용자 입장에서 스와이프가 씹힌다고 느낄 수도 있겠다.

리팩토링 방안

따라서 다음과 같이 리팩토링을 진행해보고자 한다.

리팩토링 방향성은 팀원들의 의견과 일정 추산을 고려하여 정해보고자 한다.

Swiper 컴포넌트 전체 구현 코드는 아래에서 확인해볼 수 있습니다. (0.8.3 버전)

Swiper 컴포넌트 구현 코드

profile
woowacourse FE 5th, depromeet Web 15th

3개의 댓글

comment-user-thumbnail
2024년 2월 29일

기대되는데요?!

1개의 답글