피드로 돌아가기
B2B 물류 스쿼드 백오피스 프론트엔드 성능 개선
올리브영 테크블로그올리브영 테크블로그
Frontend

B2B 물류 스쿼드 백오피스 프론트엔드 성능 개선

올리브영 B2B 물류 스쿼드가 코드 스플리팅, 폰트 압축, Nginx gzip 압축, 브라우저 캐싱을 조합해 SPA 초기 로딩 시간을 1.6~2.5초에서 0.2초로 단축

2023년 9월 25일8intermediate

Context

신규 플랫폼 오픈 후 매주 새로운 화면과 라이브러리가 추가되면서 프론트엔드 번들 용량이 증가했다. SPA의 특성상 모든 애플리케이션 파일을 한 번에 번들링하여 로드하기 때문에 초기 구동 속도가 저하되는 문제가 발생했다.

Technical Solution

  • 큰 용량 라이브러리의 코드 스플리팅 및 Webpack을 사용한 번들 분리: 필요한 라이브러리만 선택적으로 로드
  • 폰트 파일 최적화: file-loader 플러그인으로 NotoSans 폰트를 3.8MB에서 72B로 압축 (기존 .otf, .ttf 확장자를 .woff, .woff2로 변환 시도 후 실패하여 대안 적용)
  • CSS 파일 번들 최적화 및 폰트 압축 처리
  • Nginx를 통한 gzip 압축 적용: 모든 정적 리소스에 압축 수행
  • Nginx를 사용한 정적 파일 서빙 및 캐싱 정책 적용
  • axios-cache-interceptor 라이브러리로 API 응답을 Local storage에 캐싱: 반복된 API 호출을 인터셉터가 캐시된 데이터로 대체
  • Vuex를 사용한 공통 데이터(공통 코드 등) 상태 관리: 새 창 열 때마다 API를 재호출하지 않고 Local storage의 데이터를 Vuex Store에 로드

Impact

  • 초기 페이지 로딩 시간: 1.6~2.5초 → 0.7초 (최적화 후) → 0.2초 (캐싱 적용 후)
  • 초기 로딩 시 API 호출 횟수 감소 (구체적 수치 미제시)
  • NotoSans 폰트 압축률: 3.8MB → 72B

Key Takeaway

SPA 환경에서 단순 코드 스플리팅만으로는 부족하며, 정적 자산(특히 폰트)의 번들 분리, 서버 수준의 압축(gzip), 클라이언트 수준의 데이터 캐싱(Local storage + axios 인터셉터)을 계층적으로 조합해야 로딩 시간을 획기적으로 단축할 수 있다.


Vue.js 기반 SPA 서비스에서 axios를 사용 중이라면, axios-cache-interceptor로 API 응답을 Local storage에 캐싱하고 Vuex Store와 결합하여 상태를 관리하면 반복되는 API 호출을 제거하고 DOM 컨텐츠 로딩 시간을 단축할 수 있다. 동시에 내부 폰트 파일(CDN 미사용 환경)은 file-loader로 번들에서 분리한 후 Nginx gzip 압축을 적용하면 수십 MB 규모의 폰트를 KB 수준으로 압축할 수 있다.

원문 읽기