많은 옵션을 가진 Dropdown을 다루는 현명한 방법

HR·2023년 3월 28일
0

스택티콘

목록 보기
2/5
post-thumbnail

다양한 기능을 구현하다 보면, 한 번 쯤은 꼭 구현하게 되는 것이 Dropdown이다.

Dropdown은 위 사진과 같이 특정 선택에 옵션들이 존재할 때 요소의 하위에 해당 옵션들을 보여주는 것을 말한다. (출처 : w3schools)


스택티콘에서의 dropdown

스택티콘의 메인 페이지에는 다양한 stack을 선택할 수 있는 input 창과, 그에 대한 옵션을 아래와 같이 보여준다.

하지만 아래와 같은 방식에는 문제점이 있었는데, 지금 스택티콘이 가지고 있는 종류는 무려 2000개가 넘는다.

옵션들이 나타날 때마다 2400개가 넘는 요소들이 로드 되다 보니, 딜레이가 생길 수 밖에 없었다. 이 때의 딜레이는 아래와 같이 2초가 넘었고, 절대 용납될 수 없을 만큼이었다.

실제로 보면 정말 한 세월이 걸린다...


공식 문서의 제안

리액트 공식 문서의 Virtualize Long Lists 섹션 에서는 이와 같은 경우에 대한 해결책을 제시하고 있다.
여기에서 제시하는 해결책은 windowing 기법을 사용하는 것이다. 이는 목록을 가상화하고, 사용자에게 보이는 부분만 렌더링 하는 것이다.

react-window

리액트에서는 windowing 기법을 제공하는 라이브러리인 react-window가 존재한다.
해당 프로젝트 README에 있는 설명을 가져와보자면,

React window works by only rendering part of a large data set (just enough to fill the viewport).

많은 데이터 셋 중, viewport를 채우는 부분에 대해서만 렌더링을 한다고 되어 있다.

Dropdown의 모든 옵션을 보여주어야 하는 경우에는 고려하면 좋을 라이브러리라고 생각하고, 그 근거는 아래와 같다.

  1. 기존에 많은 사람들이 사용하던 react-virtualized의 제작자가 더 작고, 빠르게 재작성(rewrite)한 라이브러리이다.
  2. 사용법이 매우 간단하다.
  3. 비교적 최근(작성일 기준 22년 11월)까지 업데이트가 이루어지고 있다.

스택티콘에서는 어떻게 해결했을까?

급하게 마무리해야 하는 일도 아니었고, 기능 구현에 있어서 라이브러리 사용을 최대한 자제하려고 했기 때문에 대안책을 고민해보았다.

문제에 대한 고찰

  1. 많은 수의 svg 파일들과 text들이 같이 렌더링 되고 있다.
  2. 이미지 최적화나 lazy loading과는 별개로, 화면에 나타나는 절대적인 양이 많아서 발생한 문제이다.

해결 방법에 대한 고민

  1. 기본적으로 검색 창 하단에 노출되는 dropdown의 문제이다.
  2. 검색 창이 존재하는데도 굳이 스크롤을 내려가면서 선택을 할까?
  3. 그러면 굳이 2400개가 넘는 요소들을 모두 가져올 필요가 없겠다.

이렇게 해결 방법이 떠오르니 해결은 금방 되었다.

해결

스택티콘은 스타일링 라이브러리로 MUI를 채택해서 사용하고 있다.
MUI의 AutoComplete에 있는 filterOptions에는 Dropdown에 나타날 요소를 제한하는 limit 옵션이 존재한다.

이를 통해 dropdown에 렌더링 될 요소들의 개수를 조정해서, 문제를 해결하였다.

filterOptions={createFilterOptions({
  limit: 100,
})}

대략 3초에서 0.1초 로, 성능이 매우 개선된 것을 확인할 수 있다.


실제로 사용하는 환경에서는 훨씬 더 큰 체감이 되었다!

당장 문제를 1차원적으로 접하고 라이브러리를 찾아보는 것이 아닌, 문제의 본질이 무엇인지 고민하다 보면 해결은 의외로 쉽게 될 수가 있다는 것을 다시 한번 깨닫는다.

1개의 댓글

comment-user-thumbnail
2023년 4월 20일

저 이 부분 보고 하루 천재인가..? 생각했어요 저는 열심히 윈도잉기법을 어떻게 적용할 건지 고민하고 있었는데 개수조절이라니... 어차피 사용자들은 검색으로 자신의 스택을 찾지 전체 목록을 훑어내리지 않는다는 아이디어가 빛나는 순간이었습니다..💡

답글 달기