Skip to content

Todo 상세 좀 봤다고 테이블 전체가 재렌더링 되는건을 고치기😌

NaGyeong Park edited this page Dec 11, 2022 · 3 revisions

OAO의 주요 페이지 중 하나인 Table 페이지!

스크린샷 2022-12-12 오전 2 30 23

Todo의 데이터와 상태를 관리하고, 확인하기 위한 테이블 페이지는 OAO 서비스에 필수적이다. 그렇기에 테이블 컴포넌트는 첫 릴리즈에 무조건 구현해야되는 핵심 컴포넌트였다.

표의 초기구조 및 문제

Table은 Flex, Grid, Table(태그) 등 여러가지 방법으로 마크업 할 수 있다. 그 중 Grid를 이용해 테이블을 마크업하기로 하였는데, 아래의 이유와 같다.

  • grid-template-columns를 이용하면 열의 배치를 편하게 맞출 수 있음
  • grid-column으로 원하는 요소의 열의 비율을 조정할 수 있음
  • TableHeader와 TableRowHeader들의 비율을 일정하게 맞출 수 있음

Table 구조

Grid 구조

image
  • TableHeader 및 TableRow : 8개의 요소가 한 행씩 차지
  • TableRowDetail : 두 요소가 한 행을 차지(두 번째 요소가 7칸을 차지).

Table 컴포넌트 구조

image
  • TableRowHeader와 TableRowDetail가 한 GridWrapper 안에 감싸져있음
  • TalbleRow의 GridWrapper의 10번째 자식은 7칸을 차지함

TableRowHeader를 클릭하면 TableRowDetail이 화면에 보였다, 안보였다 하는 기능 구현

  • TableRowHeader를 감싸고 있는 태그에 onClick 이벤트를 달아주려고 하였다...
  • BUT Grid 구조 상 TableRowHeader와 TableRowDetail이 같은 태그 안에 감싸져 있어야 하기에 TableRowHeader를 감싸는 태그가 없어 onClick 이벤트를 달 수 없었다 => 현재 클릭한 TableRow의 Id를 displayDetail이라는 전역상태로 관리하고, 해당 상태의 Id와 TableRowDetail의 Id가 같다면 TableRowDetail를 보여주게 구현하였다.

그렇게 했더니,.. 아뿔싸!

🚨Table Component가 전체 재렌더링 되는 문제 발생🚨

rerender

Table에서 displayDetail 전역상태를 관리하다보니 TableRowHeader를 클릭 할 때마다 Table 전체가 리렌더링 되는 것이었다🥲 Todo의 개수가 많을 수록 렌더링 시간이 길어지는 것을 보고, 이 부분은 첫 릴리즈 이후 꼭 리팩터링 해야겠다고 마음을 먹었다.

Refactor

어떻게 리팩터링하면 좋을까

첫 릴리즈 이후 마이너 릴리즈 때 테이블에 정렬 기능, 필터 기능이 추가되었다. 리팩터링 시 표의 의미에 맞게 테이블 태그로 재구성해볼까 팀원들과 이야기해보았지만 추가된 기능에 사이드 이펙트를 일으킬 수도 있다는 판단을 내렸다. 그래서 현재 구조는 그대로 살리되, TableRowHeader와 TableRowDetail를 분리하는 쪽으로 리팩토링하기로 하였다.

최대한 작은 변경

  • TableRowHeader와 TableRowDetail를 감싸는 태그를 분리해 TableRow 컴포넌트에서 displayDetail 상태를 관리해주기

=> TableRowHeader에 onClick 이벤트를 달아줄 수 있게 되었다!

=> TableRowHeader를 클릭했을 때 displayDetail의 상태를 바꿔주어 TableRowDetail 컴포넌트를 렌더링 할지 말지를 결정해주었다. 이렇게하면 displayDetail 상태가 있는 컴포넌트들만 재렌더링되게 된다.

image

렌더링 성능 차이

  • Todo List에 Todo 20개 기준

구조 변경 전

Dec-12-2022 01-05-40

  • 첫 TableRow 클릭해 Detail 닫기 : 13ms
  • 첫 TableRow 클릭해 Detail 열기 : 13.7ms
  • 마지막 TableRow 클릭해 Detail 열기 : 11ms
  • 마지막 TableRow 클릭해 Detail 닫기 : 13ms
  • 총 렌더링 시간 : 50.7ms

구조 변경 후

Dec-12-2022 02-15-24

  • 첫 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 감소

교훈 및 반성 및 깨달음

  • 초기에 레이아웃을 잘 설정하고 시작해야지 이후 변경사항이 생겨도 사이드 이펙트를 최대한 줄일 수 있다
  • 원하는 기능을 구현하고 싶을 때 레이아웃이 이상하다면 레이아웃을 수정할 수 있을지 먼저 고민해보자
  • 상태의 위치에 따라서 재렌더링의 범위가 많이 달라지기 때문에 상태를 어디서 관리할지 깊게 고민하고 구현하자

💊 비타500

📌 프로젝트

🐾 개발 일지

🥑 그룹활동

🌴 멘토링
🥕 데일리 스크럼
🍒 데일리 개인 회고
🐥 주간 회고
👯 발표 자료

Clone this wiki locally