안녕하세요. 올영 프론트엔드 개발자 올리브정🔥 입니다!
최근 올리브영 온라인몰이 빠르게 성장함에 따라 저희 팀에서도 성능 개선을 위해 많은 고민을 하고 있습니다.
오늘은 그 고민을 해결하기 위해서 Infinite Scroll을 통한 브라우저 렌더링 최적화 방법을 알아보고자 합니다!
브라우저 렌더링 과정
사용자가 브라우저를 통해서 웹 사이트를 접속하면 브라우저는 서버로부터 HTML 문서를 파싱하고 콘텐츠 트리 내부에서 태그를 DOM 노드로 변환합니다. DOM 노드로 변환 후 외부 CSS 요소들도 파싱 합니다.
HTML 파싱이 끝나면 박스 모델(Box Model)을 순서대로 화면에 표시하는 렌더 트리를 생성합니다.
렌더 트리 생성이 끝나면 브라우저의 뷰포트 내에서 각 노드들의 정확한 위치와 크기를 계산하는 렌더 트리 배치가 시작됩니다. 이때 상대적인 위치, 크기 속성은 픽셀 단위로 변환됩니다.
마지막으로 렌더 트리 배치 과정에서 계산된 노드들의 위치와 크기를 실제로 사용자가 보고 있는 화면에 그리게 됩니다.
1️⃣ HTML 파싱
- DOM 트리 생성
- CSSOM 트리 생성
2️⃣ 렌더 트리 구축
- DOM 트리와 CSSOM 트리 결합
3️⃣ 렌더 트리 배치
- 렌더 트리를 기반으로 HTML 요소의 레이아웃(위치, 크기)을 계산
4️⃣ 렌더 트리 그리기
- 화면에 HTML 요소를 페인팅
앞서 소개해 드린 브라우저 렌더링 과정을 개선할 수 있는 방법으로는 다음의 방법들이 있습니다.
Reflow/Repaint 최소화
특정 액션이나 이벤트에 따라서 HTML 요소의 크기나 위치 등 레이아웃 수치가 수정됩니다. 그에 영향을 받는 자식 노드나 부모 노드들을 포함하여 레이아웃 과정을 다시 수행하는 Reflow와 그 결과물을 다시 화면에 그려주는 Repaint를 최소화하는 방법으로 최적화할 수 있습니다.
영향을 주는 노드 최소화
레이아웃 변화가 많은 요소의 경우 포지션 속성을 absolute나 fixed 옵션을 사용하여 영향을 주는 노드를 최소화하는 방법으로 최적화할 수 있습니다.
프레임 줄이기
화면에 움직이는 요소가 있을 경우 이동 간에 부드러운 효과를 조금 줄이는 방법으로 최적화할 수 있습니다.
CSS will-change 속성 사용
렌더링 이후 변화가 일어날 것 같은 요소에 "will-change: 속성이름" 속성을 사용해주는 방법으로 최적화할 수 있습니다.(다만 이를 남발해서 사용하면 안됩니다.)
지금까지 일반적인 브라우저 렌더링 과정을 살펴보고 이를 개선할 수 있는 최적화 방법을 살펴보았습니다.
오늘 알아볼 Infinite Scroll은 현재 화면에 보이는 부분만 렌더링 하여 불필요하게 사용되는 리소스를 줄여 렌더링을 최적화할 수 있는 방법입니다.
Infinite Scroll 설명
Infinite Scroll 이란 페이지 로딩 시 사용자가 화면으로 볼 수 있는 영역(Viewport)의 엘리먼트만 생성하여 렌더링하고 보이지 않던 영역을 스크롤 할 때는 필요한 엘리먼트를 추가하여 렌더링 하는 기법입니다.
페이지 로딩 시 화면에 표현되는 모든 엘리먼트를 생성하지고 않고 사용자가 보고 있는 영역에 엘리먼트만 추가할 수 있다 보니 대량의 데이터를 처리해야 하는 웹 사이트에서 많이 활용되고 있는 추세입니다.
Infinite Scroll 관련 라이브러리로는 대표적으로 react-infinite-scroll-component와 react-infinite-scroller가 있습니다.
Infinite Scroll 적용
보시는 화면은 현재 저희 팀에서 개발하고 있는 올리브영 온라인몰 신규 아키텍처(React 전환) 버전입니다. 페이지 최초 로딩 시에는 해당 노드에 엘리먼트들이 모두 생성되지 않았지만 스크롤 이벤트가 발생할 때마다 사용자가 현재 보고 있는 영역에 해당하는 엘리먼트들이 추가되고 있는 걸 확인하실 수 있습니다.
저희 팀에서는 해당 기능을 구현하기 위해서 Infinite Scroll 관련 라이브러리 사용을 검토했지만 커스텀이 불편하다는 점과 빌드 파일 크기를 조금이나마 줄여보고자 이 기능을 직접 구현했습니다.(우리 팀 최고👍)
Infinite Scroll 효과
적용 전
적용 후
개발자 도구를 통해서 확인해 본 결과 FCP/LCP 속도 등 전체적으로 소요시간이 줄어들었습니다. 페이지 로드 시에 화면에 보이지 않는 엘리먼트들을 모두 생성하게 되면 클라이언트 자원을 많이 소모하기 때문에 이런 속도 차이를 보이고 있습니다.
페이지 내에 표현해야 하는 엘리먼트가 많은 경우 Infinite Scroll 기법을 활용하면, 초기 로딩 속도를 단축시킬 수 있고, 스크롤 이동 시 딜레이 현상도 개선할 수도 있습니다.
마무리
지금까지 브라우저 렌더링 과정부터 Infinite Scroll 효과까지 알아보았습니다.
저희 팀에서는 이 방법 말고도 사용자분들이 좀 더 쾌적하게 올리브영 온라인몰을 이용하실 수 있도록 고민하고 개선하고 있습니다. 많은 응원 부탁드리며 이만 마치겠습니다. 감사합니다!