-
04. 렌더링 최적화(2) Recalculation-style 시간 줄이기Projects/세계 여행 지도 2021. 6. 4. 10:53
빌드 버전을 실행해서 Performance 탭을 확인 해 보니, mouse over 이벤트에 의한 연산 등 많은 부분에서 성능이 올라갔지만, Recalculation-Style이라는 부분에서 여전히 40ms정도의 시간이 걸리고 있었다. (아무래도 컴포넌트가 많은 것도 한 몫 하겠지?)
Reacalculation-Style이요?
전에 포스팅에서 언급한 렌더링 순서에 대해 간단하게 다시 정리하자면 최초에 페이지를 불러오게 되면 브라우저는 다음과 같은 순서로 페이지에 렌더링을 하게된다.
1. HTML 파일을 위에서 아래로 한 줄씩 차례대로 읽어 tag들을 파싱해 DOM Tree를 만들어나간다.
2. 중간에 link tag를 만나면 HTML 파싱을 중단하고 CSS 파일을 요청받아 CSSOM Tree를 만들어 나간다.
CSS파일 파싱이 모두 끝나면 계속해서 HTML 파일을 파싱한다.
3. 완성된 DOM Tree와 CSSOM Tree를 합쳐서 Render Tree를 만든다.
4. Render Tree에 형성된 각 노드들의 위치와 크기를 계산해 배치(Layout)하고 그린다(Paint).자 그러면 유저의 인터렉션이나 애니메이션등으로 인해 Style의 일부가 변경된다면 어떤 순서로 업데이트가 되는 것일까? 전체적으로 보면 다섯 단계의 순서를 거친다.
- 자바스크립트. 일반적으로 자바스크립트는 페이지에 DOM 요소 추가를 하거나 백엔드로 부터 데이터를 불러와서 페이지를 동적으로 생산하는 등 시각적 변화를 일으키는 작업을 처리하는 데 사용된다.
- 스타일 계산. 이는 .headline 또는 .nav > .nav__item 등의 매칭 선택기에 따라 어떤 CSS 규칙을 어떤 요소에 적용할지 계산하는 프로세스. 여기에서 규칙이 알려지면 적용되고 각 요소의 마지막 스타일이 계산된다.
- 레이아웃. 50%, em, calc 등 css 내에서 크기와 위치에 대한 계산이 필요한 부분을 연산한다.
- 페인트. Style 대로 그려낸다.
- 합성(Compositing). 페이지의 여러 부분이 잠재적으로 여러 레이어로 그려졌기 때문에 정확한 순서로 여러 레이어들을 하나씩 그려낸다.
그래서 Recalculation Style 이란 업데이트 요소가 생겼을 때 위에서 두번째 단계에 해당하는 css 규칙을 다시 계산하는 것임을 알 수 있다.
그렇다면 여행 앱에서는 Layot, Paint, Composite부분이 아닌 Style부분에서 압도적으로 시간이 많이 드는데, 어떤 녀석이 이렇게 Style부분에서 재계산이 일어나는 걸까??
.
한참 찾아보다가 범인을 찾았다..! 범인은 바로 마우스를 올렸을 때 나타나는 이 Tooltip인데, Mousemove 이벤트를 받아서 clientX, clientY를 계속해서 업데이트 해주고, 그 위치를 받아 tooltip의 위치를 변경하고 있기 때문이었다.
그래서 라벨을 마우스 옆이 아닌 지도 아래 부분에 띄워 주니 툴팁의 위치에 대한 계산을 계속해서 해 주지 않아도 되기 때문에 성능이 눈에 띄게 향상되었다.
성능 향상 vs 편리성
성능 향상으로 인한 UX는 개선 되었지만 라벨이 사용자가 움직이는 마우스의 근처가 아닌 하단에 고정되어 버림으로서 인터렉션에 대한 UX는 떨어졌다...
두 마리 토끼를 다 잡을 수 있는 좋은 방법은 없을까?? 조금 더 고민 해봐야겠다.
참고
'Projects > 세계 여행 지도' 카테고리의 다른 글
05. media 쿼리와 CSS 속성[Attribute] 선택자로 다크모드 구현하기 (0) 2021.06.04 03. 렌더링 최적화(1) Memoization을 통한 리렌더링 최소화 (0) 2021.06.03 02. 컴포넌트화를 통한 호버링 하이라이트 (feat. Styled Component) (0) 2021.06.03 01. Grid로 세계 지도 나타내기 (0) 2021.06.03