-
Notifications
You must be signed in to change notification settings - Fork 1
아토믹 디자인 패턴 도입
처음 개발할 당시 전체적인 DOM 구조는 아래와 같았다.
<div>
<div class="desktop-layout">
...
</div>
<div class="mobile-layout">
...
</div>
</div>
데스크탑과 모바일 각각의 UI가 달라서 선택한 차선책이었다.
아래 그림을 보면 Side bar의 경우 데스크탑에만 있고, Drawer의 경우 모바일에만 있다.
그리고 모바일UI에서는 검색바와 버튼이 지도 위에 있어야 하고, 헤더의 구조도 조금 다르다.
DeskTop | Mobile |
---|---|
이러한 부분들이 media query로만 사용해서 해결하기에는 어려운 부분이 있어 고민하다가 위와 같은 구조로 구현한것이었다.
문제는 같은 데이터 요청이 두번씩 간다는 것이었다.
렌더링 과정을 보면
-
가상돔 생성
-
DOM 트리 구축, CSSOM 트리 생성, 자바스크립트 파싱 후 실행
-
렌더트리 구축
-
layout 구성, 페인팅
...
이런 과정으로 실행된다.
데스크탑 환경에서 실행해서 mobile ui를 display:none으로 숨기면, 렌더 트리에는 반영이 안되지만 가상돔이 생성되고 DOM 트리 구축하는 과정에서는 display: none인 element도 반영이 되기 때문에 데이터 요청이 가게된다.
즉 데스크탑 환경에서 실행하면 mobile ui는 display none이라 렌더트리에는 반영되지 않지만 자바스크립트 로직은 실행되어서 데이터 요청을 보내게 된다. 데이터 요청을 보내는 컴포넌트가 2개씩이니 당연히 요청이 두번 가게된다.
이를 해결하기 위해 Atomic design 패턴을 사용했다.
https://yozm.wishket.com/magazine/detail/1531/
위의 글을 많이 참고 했는데, 요약하자면 컴포넌트 layer를 아래 그림과 같이 두고 레고를 조립하듯이 컴포넌트를 재사용하고 조립하여 더 큰 컴포넌트, 그다음 컴포넌트, 그렇게 해서 최종 페이지를 구성하자는 게 핵심 아이디어이다.
우선 가장 작은 단위인 atom으로 사용할 컴포넌트를 먼저 구현하고, 그 다음 필요한 컴포넌트들을 구현하여 molecules와 organisms으로 구분 지었다.
도입해보고 느낀점은 molecules와 organisms 경계가 참 모호하다는 것이었다..
나만의 주관적인 기준을 가지고 나누긴 했으나 이것이 옳은지는 모르겠다. 다른 레퍼런스들을 찾아보니 다른 분들도 많이 고민하시는 부분인거 같았다.
나만의 주관적인 기준은 페이지 내에서 특정한 한 부분을 크게 담당하고 있으면 organisms으로 넣었다. header, sidebar, drawer등등..
루트 컴포넌트에서 훅을 통해 api요청을 보내 전역 상태로 저장하고, 각각의 컴포넌트에서는 전역 상태를 가져다 사용하기 때문에 두번씩 요청이 보내지지 않는다. 각 컴포넌트 UI와 렌더링 여부는 미디어 쿼리를 통해 조절해주었다.
구현해둔 컴포넌트 들을 아래와 같이 page에서 조립했다.
<Wrapper>
<SideBar isLoading={isLoading || isGetLocation} />
<TobBar />
<Section>
{!search && !id && <Filter />}
{isGetLocation ? (
<LoadingContainer>
<Loading />
</LoadingContainer>
) : (
<Map />
)}
</Section>
<Drawer isDetail={!!id}>
{id ? <Detail /> : <PlaceList isLoading={isLoading || isGetLocation} mobile />}
</Drawer>
</Wrapper>
이런식으로 컴포넌트 중복 사용을 막아서 api 요청을 한번씩만 가도록 수정하였고, 컴포넌트 구조도 한눈에 들어오게 수정하였다. SideBar는 데스크탑 UI에서만 렌더링되고, TobBar와 Drawer는 모바일 UI에서만 렌더링된다.