솔드아웃 상품 상세 페이지 렌더링 속도개선

function_dh·2024년 3월 28일
1
post-thumbnail

개선 배경

기존 솔드아웃 상품 상세 페이지의 경우 진입시 상당한 긴 렌더링 시간을 가지고 있었습니다..

그 이유는 상품 상세 data 관련 api 통신이 완료되기 까지 빈화면인 상태로 무한히 대기 할 수 밖에 없는 구조로 되어 있었기 때문인데요

이러한 부분이 반복되다 보면 커머스적으로 심각한 문제이기도 하고 사용자 입장에서 불편한 경험이 쌓이게 되어 유저의 이탈이 많아 질 것으로 생각이 되었습니다.

따라서 렌더링이 느려지는 요소를 분석하여 상품 상세 페이지의 렌더링 속도를 개선하기로 했습니다! 🤓

문제점들

  1. 상품 상세 api가 너무 많은 data를 가지고 있어 서버 응답이 오래 걸리는 이슈
  2. 해당 api의 data가 없을 경우 상품 상세 페이지 전체를 노출하지 않아 로딩창만 보이는 이슈
  3. 제품 상세 페이지 진입시 보이지 않는 영역의 컴포넌트까지 한번에 렌더링 되는 이슈

프론트 이슈가 아닌 부분도 있지만 충분히 백엔드 작업자 분과 협의하여 해결할 수 있을 거라 판단하여 위 문제점들을 토대로 개선을 진행하기로 하였습니다.

개선 내용정리 (요약)

  • 제품 상세 api - productDetail가 너무 많은 data를 가지고 있어 서버 응답이 오래 걸리는 이슈
    • 해당 페이지에서 모든 data가 하나의 api에서만 처리하고 있었기 때문에 api 분리 요청을 드려서 기본적으로 첫 페이지 진입시 보여지는 컨텐츠 영역에 한정하여 api 분리 요청
    • 상세페이지 기본 정보 api 추가 - basic api 로 초기 렌더링을 변경하여 서버 응답 줄이도록 처리
  • 상품상세 페이지 진입시 상품상세 api data 값이 없으면 페이지를 노출하지 않음
    • 상품상세 페이지 진입 후 바로 보여지는 컴포넌트의 경우 기본 data init값을 넣어주어 layout을 유지하도록 변경
    • api 분리로 인하여 초기 로딩 속도가 개선되어 의미가 없어진 Loading 컴포넌트는 제거
  • productDetail(제품 상세 api data)로 모든 상품상세 값을 제어하고 있어서 값이 바뀌면 리렌더링 되기 때문에 최적화 필요
    • productDetail에 있던 data를 컴포넌트 별로 분리
    • viewLogicMethods 를 분리하여 각 컴포넌트 별 data 세팅을 분리하여 처리
  • 제품 상세에 진입 시 첫 로드시 많은 컴포넌트가 한번에 렌더링 되기 때문에 속도가 느림
    • observer 기능을 활용하여 해당 컴포넌트에 도달 했을 때 data 적용하도록 수정
    • 상품 특성, 다른 고객이 함께 본 상품, 연관 추천 컨텐츠 등 페이지 하단에 위치한 컴포넌트 위주로 처리

개선 상세 내용

  1. 기존 페이지에서 상품 상세 api 관련 data를 모두 처리하여 api 통신이 끝나기 전까지 화면 노출이 되지 않아 상세 페이지 로딩 속도가 느리게 느껴지는 점이 있었습니다.
    • basic api를 사용하여 첫 화면 진입시 보이는 data와 meta tag 세팅을 진행하여 SEO 부분도 함께 처리하였습니다.
  2. 위와 같이 변경하면서 productDetail data에 의존하던 컴포넌트의 경우 모두 에러가 발생하여 기본값으로 init data를 초기에 세팅한 후에 mounted에서 promise all을 활용하여 api가 호출 완료 되기 전까지 화면이 페인팅 될 수 있도록 수정하였습니다.
  3. mounted에서 api 호출이 완료되면 viewLogicMethods.setItemDetail() 메소드가 동작하여 각 컴포넌트에서 활용하는 data로 분리되어 값을 할당하게 됩니다.
데이터 할당 관련 예시
  1. 가장 로딩이 느린 차트 컴포넌트의 경우도 페이지 첫 로딩시 해당 컴포넌트에서 차트 관련 data를 설정 하는 것이 아니라 상품상세 컴포넌트 mounted부분으로 변경하여 promise all 부분에 포함되어 초기 로딩속도가 빨라졌습니다.

  2. 상품 상세 하단 영역의 경우 불필요한 서버 렌더링을 줄이기 위해 보이지 않는 부분의 컴포넌트는 client-only 처리 하였습니다.

  3. 제품 특성 안내 팝업, 연관 추천 콘텐츠의 경우 어드민에서 에디터를 통해서 값이 들어가기 때문에 이미지 같은 경우 원본 이미지가 전송되어 상당히 큰 이미지를 가지고 있었습니다. (2000x1500)

    따라서 해당 부분에 observer 기능을 적용하여 첫 페이지 로딩시가 아닌 해당 컴포넌트에 스크롤이 도착했을 경우 값을 할당 되게 변경하였습니다.

그래서 속도가 얼마나 빨라 졌는데?

속도 테스트는 stage 서버 기준으로 작성 되었습니다.

LightHouse
접근성 부분도 같이 변경하여 24점 상승 → 86점
seo 8점 상승 → 100점
퍼포먼스의 경우 10점이 상승 → 63점

⬆️개선전 stage

⬆️개선후 stage

Performance
FCP (First Contentful Paint) 1.8초 → 0.7초
LCP (Largest Contentful Paint) 2.9초 → 2.3초

⬆️개선전 performance

⬆️개선후 performance

실제로 느껴보자!

FCP (First Contentful Paint) - 1.87초
LCP (Largest Contentful Paint) - 1.98초

FCP (First Contentful Paint) - 0.46초
LCP (Largest Contentful Paint) - 1.56초

위의 이미지에서 처음 레이아웃이 그려지는 시간, data가 컴포넌트에 세팅되어 렌더링이 완료되는 시점에 중점을 두어 보면 좋을 것 같습니다 :)

마무리

생각보다 좋은 결과가 나오게 되었는데요! 이번 작업을 통하여 FCP의 경우 1.4초, LCP의 경우 0.4초 정도 렌더링이 빨라지게 되었습니다!

작업을 진행하면서 너무나 많은 부분들이 잘못 되어 있고 개선할 방향이 앞으로도 많이 남았기 때문에 (이미지 렌더링 처리, 역할에 따른 컴포넌트 분리 등) 추가적인 작업을 꼭! 진행해야겠다는 반성도 하게 되었습니다.

하지만 한편으로는 하나씩 풀어가다보면 얽혀있는 실도 풀 수 있듯이 꾸준하게 개발적으로 옳은 방향으로 나아가려고 하는 것 같아 만족스러운 부분도 있다 생각합니다.

작업을 진행하면서 test시에 버그 제보를 주신 팀원 분들과 상품상세 개선 관련하여 많은 초석을 다진 같은 파트인 용문님께 감사 인사 드립니다 👍

profile
🍄 성장형 괴물..

0개의 댓글