본문 바로가기

카테고리 없음

[TIL] 프로그래머스 데브코스 - 바닐라JS/ SPA구조로 노션만들기 -토글기능(+ 약간의 리팩토링).

배포 사이트 : https://vanilla-js-notion-4cckycphd-gangpyono.vercel.app/

이전에 토글기능을 넣었지만 특정 페이지를 편집중에 새로고침을 눌렀을때 해당 문서가 자식문서임에도 불구하고 토글이 모두 닫혀 왼쪽 배너부분에서의 정확한 위치표시가 안됨 + 아래 문제부분에서의 의문이 있어 주말을통해 개선하고자했다. 

 

1. 문제

서버로부터 토글에 대한 상태를 받아오지 않기 때문에 토글 버튼을 클릭할 때마다 전역에서 관리하는 배너 상태에 임의로 상태 값을 넣어주고 상태 변경에 의한 렌더링으로 보여주고 있었다.

여기서 문제가 총 2가지가 발생했는데 

첫 번째로는.

토글 상태를 배너부분외에서 사용하지않을것같은데 전역상태로 관리할 필요가 있는가? -> 토글상태를 전역 상태 관리에서 분리.

두 번째로는.

에디터 페이지에서 새로고침을 눌렀을떄 토글 상태가 초기화된다. -> 이는 서버로부터 토글 상태에 대한 데이터를 받아오지 않기 때문에 당연한 결과.

두번째 문제

두 가지 문제를 모두 해결하기 위해선 토글의 상태를 별도로 브라우저에 저장해야 했고 아래와 같은 구현 과정을 설정해보았다.

 

2. 구현 과정.

  1. 토글 상태를 전역으로 관리할 필요가 없다.
  2. 페이지를 닫았다가 다시 접속했을 때 유지할 필요가 없기 때문에 로컬 스토리지보단 세션 스토리지 사용.
  3. 토글이 활성화된 문서의 id를 세션 스토리지에 저장하고 토글을 닫는다면 세션 스토리지에서 id를 제거.(세션 스토리지에서 해당 id를 찾는 과정에서 시간 복잡도를 고려하여 값을 객체로 관리)
  4. 위에서 저장한 세션 스토리지의 데이터를 참조하여 왼쪽 배너 부분의 view를 그린다.

3. 돔 업데이트 최소화.

  1. 토글 상태를 브라우저의 세션 스토리지에서 관리하기도 하고 토글은 순전히 view에서만 보이기 때문에(서버로 데이터를 전송할 필요가 없기 때문에) 다른 기능처럼 상태 변경 -> 렌더링 방식으로 전체 돔을 다시 그리는 방식이 아닌, 직접 돔에 접근하여 토글을 원하는 돔만 업데이트하는 방식으로 렌더링 시킴.

왼쪽 : 토글을 상태로 관리하여 렌더링하는 코드 / 오른쪽 : 화면에 직접 접근하여 렌더링하는 코드

이전엔 이벤트로 처리하는 방식이었다면, 돔에 직접 접근하여 변경하는 방식으론 쿼리 실렉터로 찾는 과정, text수정 부분이 추가되어 코드가 길어지긴 한다.

리팩토링 전
리펙토링 후

리팩터링 전엔 토글이 발생했을 때마다 왼쪽 배너의 돔 요소가 전체적으로 업데이트가 발생하는데, 리팩터링 후엔 해당 돔 요소만 업데이트가 발생한다.

이로써 코드의 가독성이 떨어지지만, 돔 업데이트의 부하는 줄일 수 있게 되었다.

 

4. 세션 스토리지에서 관리중인 토글 상태들을 배열이아닌 객체로 관리.

 세션스토리지에 배열로  토글 상태들을 관리하게 된다면 새로고침 시 배너를 그릴 때 각 문서의 토글 상태를 검사하기 위해 세션 스토리지의 모든 ID값을 순회하여 있는지 없는지 판단 후 그리게 된다.

이를 시간 복잡도 측면에서 보면 화면을 그리는 과정 O(n)과 토글 상태검사 O(n)으로 O(n^2)가 되버리게된다. 따라서 복잡도를 조금이라도 낮춰보고자 토글상태 검사는 객체로 관리하여 ID값으로 바로 찾는(O(1))방식을 생각해보았다. (뭐 그렇게 큰 차이는 없는데.. 뭔가 이중 포문에 대한 거부감..? 이 있어 공부 겸 적용해보았다.)

 

세션스토리지에 토글상태를 저장하는 과정.
화면에그릴때 토글상태 확인과정.

노란색으로 밑줄 그어진 부분이 세션 스토리지에 저장하는 과정과 돔을 그릴 때 참조하는 과정이다. 키값으로 id를 적용하여 저장함으로 O(1) 방식으로 저장, 참조할 수 있다.

 

5. 결론

돔에 직접 접근하여 업데이트, 객체로 토글 상태 관리함으로써 돔 업데이트 최소화 + 시간 복잡도 개선을 통해 리팩터링을 진행해보았다.