-
Notifications
You must be signed in to change notification settings - Fork 1
Todo 상세 좀 봤다고 테이블 전체가 재렌더링 되는건을 고치기😌

Todo의 데이터와 상태를 관리하고, 확인하기 위한 테이블 페이지는 OAO 서비스에 필수적이다. 그렇기에 테이블 컴포넌트는 첫 릴리즈에 무조건 구현해야되는 핵심 컴포넌트였다.
Table은 Flex, Grid, Table(태그) 등 여러가지 방법으로 마크업 할 수 있다. 그 중 Grid를 이용해 테이블을 마크업하기로 하였는데, 아래의 이유와 같다.
-
grid-template-columns
를 이용하면 열의 배치를 편하게 맞출 수 있음 -
grid-column
으로 원하는 요소의 열의 비율을 조정할 수 있음 - TableHeader와 TableRowHeader들의 비율을 일정하게 맞출 수 있음

- TableRowHeader와 TableRowDetail가 한 GridWrapper 안에 감싸져있음
- TalbleRow의 GridWrapper의 10번째 자식은 7칸을 차지하여 TableRowHeader와 TableRowDetail의 div태그 10개가 쌓여 2행을 차지함

-
TableRowHeader를 감싸고 있는 태그에 onClick 이벤트를 달아주려고 하였다...
-
BUT Grid 구조 상 TableRowHeader와 TableRowDetail이 같은 태그 안에 감싸져 있어야 하기에 TableRowHeader를 감싸는 태그가 없어 onClick 이벤트를 달 수 없었다 => 현재 클릭한 TableRow의 Id를 displayDetail이라는 전역상태로 관리하고, 해당 상태의 Id와 TableRowDetail의 Id가 같다면 TableRowDetail를 보여주게 구현하였다.
-
displayDetail(boolean)을 전역상태로 가져 상태에 따라 TableRowDetail의 렌더링 여부를 결정
-
Table 컴포넌트에서 TableRow에 onClick 이벤트 발생시 displayDetail의 상태를 변경하기 때문에 Table 관련 컴포넌트는 전부 렌더링 됨
그렇게 했더니,.. 아뿔싸!
Table에서 displayDetail 전역상태를 관리하다보니 TableRowHeader를 클릭 할 때마다 Table 전체가 리렌더링 되는 것이었다🥲 Todo의 개수가 많을 수록 렌더링 시간이 길어지는 것을 보고, 이 부분은 첫 릴리즈 이후 꼭 리팩터링 해야겠다고 마음을 먹었다.
첫 릴리즈 이후 마이너 릴리즈 때 테이블에 정렬 기능, 필터 기능이 추가되었다. 리팩터링 시 표의 의미에 맞게 테이블 태그로 재구성해볼까 팀원들과 이야기해보았지만 추가된 기능에 사이드 이펙트를 일으킬 수도 있다는 판단을 내렸다. 그래서 현재 구조는 그대로 살리되, TableRowHeader와 TableRowDetail를 분리하는 쪽으로 리팩토링하기로 하였다.

- TableRowHeader와 TableRowDetail가 다른 Wrapper에 감싸져있음
- TableRowHeader는 8개로 한 행을 만듬
- TableRowDetail는 2개로 한 행을 만듬

- displayDetail(boolean)을 TableRow 컴포넌트에서 가지고있어 상태에 따라 TableRowDetail의 렌더링 여부를 결정
- TableRow 컴포넌트에서 TableRowHeader에 onClick 이벤트 발생시 displayDetail의 상태를 변경하기 때문에 TableRow 관련 컴포넌트는 전부 렌더링 됨
클릭한 TableRow 컴포넌트만 재렌더링이 일어난다.
- Todo List에 Todo 20개 기준
- 첫 TableRow 클릭해 Detail 닫기 : 13ms
- 첫 TableRow 클릭해 Detail 열기 : 13.7ms
- 마지막 TableRow 클릭해 Detail 열기 : 11ms
- 마지막 TableRow 클릭해 Detail 닫기 : 13ms
- 총 렌더링 시간 : 50.7ms
- 첫 TableRow 클릭해 Detail 닫기 : 2.8ms
- 첫 TableRow 클릭해 Detail 열기 : 1.4ms
- 마지막 TableRow 클릭해 Detail 열기 : 1.8ms
- 마지막 TableRow 클릭해 Detail 닫기 : 1.3ms
- 총 렌더링 시간 : 7.3ms
- 첫 TableRow 클릭해 Detail 닫기 : 기존 시간의 22%
- 첫 TableRow 클릭해 Detail 열기 : 기존 시간의 10%
- 마지막 TableRow 클릭해 Detail 열기 : 기존 시간의 16%
- 마지막 TableRow 클릭해 Detail 닫기 : 기존 시간의 10%
- 총 렌더링 시간 : 기존 시간의 14% => 43.7ms 감소
- 초기에 레이아웃을 잘 설정하고 시작해야지 이후 변경사항이 생겨도 사이드 이펙트를 최대한 줄일 수 있다
- 원하는 기능을 구현하고 싶을 때 레이아웃이 이상하다면 레이아웃을 수정할 수 있을지 먼저 고민해보자
- 상태의 위치에 따라서 재렌더링의 범위가 많이 달라지기 때문에 상태를 어디서 관리할지 깊게 고민하고 구현하자
- OaO 환경설정 A to Z
- CRLF 너가 뭔데 날 힘들게 해?
- Github Issue 똑똑하게 사용하기
- OAO! CI CD 적용기 with release 자동화
- 매번 다른 import문
- 못생긴 상대경로에서 간zlzl존 절대경로로😎
- TodoList API 개발기
- 의존성 주입으로 DB를 바꿔보자
- 렌더링 최적화 서막: useNavigate를 추가한 순간 리렌더 범위가 확장된 건에 대하여
- 렌더링 최적화 1탄: 렌더링 범위에 대하여 (by 최적화무새)
- 렌더링 최적화 2탄: 잘못된 custom hook 사용,, 전체 리렌더링을 부르다,,
- 렌더링 최적화 3탄: Todo 상세 좀 봤다고 테이블 전체가 재렌더링 되는건을 고치기😌
- 렌더링 최적화 4탄: 다이어그램 편
- 🐁 마우스 상대위치 계산은 이상해
- React 컴포넌트에 애니메이션을 적용해보자 🏃🏻💨
- 컴포넌트 재사용성을 높여보자: Modal 분리기 🌹
- 선후관계를 자동완성으로 추가해보자 🔎