GSShop 모바일 웹 속도 개선 케이스스터디

GSShop 모바일 웹 속도 개선 케이스스터디

@July 8, 2020

나는 GSShop의 CoE 중 한 명으로, 회사가 투자한 스타트업이 잘 성장할 수 있도록 돕고 있다. 그리고 이번엔 그간 스타트업과 일했던 경험을 살려 GSShop의 모바일 웹사이트의 속도 개선 프로젝트를 진행할 기회가 만들어졌다. 이 글은 마이크로 서비스팀과 프로젝트를 진행하며 얻은 경험을 공유하기 위한 케이스스터디이다.

# 느린 상품 페이지

https://web.dev/value-of-speed/

느린 속도는 사용자 경험에 좋지 않은 영향을 끼치고, 이는 전환율에도 영향을 끼칠 수 있다는 많은 케이스스터디가 있다. 그리고 상품 페이지는 네이버 가격비교 등을 통해 외부 고객이 들어오는 중요한 통로이다. 그러나 GSShop의 상품페이지는 느린 속도로 인해 좋지 않은 사용자 경험을 주고 있었다. 그중에도 '딜' 페이지라 부르는 다수의 상품을 모아놓은 상품 페이지의 속도는 더욱 좋지 않았다. 때문에 상품페이지의 속도 개선은 꼭 필요한 상태였다.

# 속도 측정

## 사용자 경험을 반영한 지표

웹 속도 측정은 구글의 User-centric performance metrics를 따르는 것이 일반적이다. 이들 지표 중 LCP(Largest contentful paint)는 사용자 경험에 중요한 요소를 얼마나 빠르게 그리는지 측정하는 기준이 된다. LCP는 보다 안정적으로 사용자 경험을 반영할 수 있기에 FMP(First meaningful paint)를 대체하고 최근 표준으로 자리 잡고 있다. 이 케이스스터디는 LCP를 기준으로 작성하였다.

image

## 경쟁사 속도 측정

경쟁사는 사용자 경험에 따라 우리 서비스를 대체할 수 있다는 점에서 경쟁사와의 속도 비교는 중요하다. 아래 차트는 홈쇼핑 11개사의 딜 상품 페이지의 LCP를 측정한 것이다. 변수를 없애기 위해 WebPageTest를 사용하였고, 모든 테스트에서 Seoul, EC2, Chrome, Emulated iPhone X, LTE, Mobile로 동일한 환경으로 측정했다. 로딩 속도 측정은 상품 페이지 상단 대표 이미지가 노출되는 시간으로, 각 회사별 18회 측정하여 가장 작은 값을 기록했다. 이를 통해 다른 홈쇼핑사들에 비해서도 느리다는 것을 확인했다.

# 개선 프로젝트

GSShop은 이미 Vue.js를 상품 페이지에 일부 적용하고 있고, 다양한 성능 개선 방안을 제공해 주는 Nuxt.js를 도입하는 것이 최선이다. 그러나 GSShop은 매우 복잡하고 거대한 웹 서비스이다. 안정적인 진행을 위해 이번 개선 프로젝트의 범위는 기존 자바 웹 서버를 변경하지 않는 선에서 모바일 웹의 단품/딜 상품 페이지로 한정했다.

## 개선 과제 진단

속도 개선 진단 최고의 도구는 Google의 Lighthouse이다. 크롬 개발자 도구에서 쉽게 접근할 수 있으며, 훌륭한 진단을 내려준다. 그러나 어디까지나 자동화된 진단 도구이며, 정확한 진단과 개선 방안은 Performance profile을 통해 이루어지게 된다. 이를 위한 지식은 구글의 web.devweb fundamentals에 잘 정리되어 있다. GSShop의 상품 페이지를 진단하여 아래의 9가지 개선 과제를 도출했다.

  • 인라인 스타일 + 미사용 스타일 제거
  • 렌더링 방해 스크립트 비동기화
  • 스크립트 우선순위 재조정
  • 주요 요소 선제 로딩
  • 이미지 압축
  • 화면 밖 이미지 지연 로딩
  • 스크립트 축소
  • HTTP/2 적용
  • 리소스 힌트 적용

이 케이스스터디에서는 그중 영향이 큰 몇 개의 과제만 소개하겠다.

## 인라인 스타일 + 미사용 스타일 제거

image

브라우저는 스타일을 발견하면 스타일을 다운로드하고 처리할 때까지 HTML 파싱을 멈추게 된다. 스타일은 대부분 크지 않은 용량이나, 다운로드하기까지 필요한 Queueing, Stalled, Initial connection, TTFB 시간이 압도적으로 길다. 상품 페이지의 스타일을 다운로드하는데 걸리는 시간은 4.85ms에 불과하지만, 이를 위해 기다리는 시간은 이보다 훨씬 길다. 스타일을 HTML에 인라인 시키면 기다리는 시간 400ms를 절약할 수 있게 된다.

## 랜더링 방해 스크립트 비동기화

image

스크립트 역시 스타일과 마찬가지로 브라우저의 main thread에서 처리되는 존재다. 즉 스크립트를 만나면 브라우저는 스크립트를 처리할 때까지 렌더링을 멈추어야 한다는 뜻이다. 스타일과 다른 점은 스타일은 HTML을 렌더링을 하는데 즉시 필요한 반면, 스크립트는 대부분 HTML이 완전히 파싱 된 이후에 필요하다는 점이다. 때문에 스크립트는 인라인 시키는 것보다 defer를 통해 DOMContentLoaded 이후에 처리되도록 하는 것이 좋다. 위 스크린샷의 Main thread의 Parse HTML(푸른색) 중간에 들어있는 Evaluate script(노란색) 그리고 유휴 시간을 줄일 수 있다. 약 350ms의 단축 효과가 있다.

## 스크립트 우선순위 재조정

image

화면을 그리는데 필수인 스타일과 스크립트보다 서드파티 스크립트들을 먼저 처리하고 있다. ascend.js, pixlee_events.js, enliple_min2.js 등 서드파티 스크립트들은 화면이 그려진 이후에 처리해도 문제없다. 전체 스크립트들을 우선순위에 맞게 아래의 순서로 재 배치했다. 이를 통해 450ms 가량을 개선할 수 있다.

  1. 화면을 그리는데 필요한 스크립트
  2. 화면을 동작 시키는데 필요한 스크립트(예: slider)
  3. 사용자 동작을 처리하는데 필요한 스크립트
  4. 기타 서드파티 라이브러리

스크립트의 우선순위는 스크립트의 위치나 속성을 통해 변경할 수 있다. JavaScript Loading Priorities in Chrome을 참고하자.

## 주요 요소 선제 로딩

image

상품페이지의 상단 대표 이미지(27411045_L1.jpg)가 Main thread의 Evaluate Script(노란색) 처리 이후 로드되는 것을 확인할 수 있다. 이는 캐러셀 스크립트가 실행된 이후에야 캐러셀이 이미지를 다운로드하기 시작하기 때문이다. 그러나 대표 이미지는 캐러셀 스크립트와 별개로 이미 알고 있는 이미지이다. 이를 미리 다운로드하면 캐러셀 스크립트를 처리함과 동시에 이미지를 보여줄 수 있다. 페이지 상단에 preload 하여 처리할 수 있다. 또한 상품 페이지 이전(ex: 검색 결과)에 prefetch 하는 방법도 적용할 수 있다. 이미지를 다운로드하는데 걸리는 200ms 가량을 절약했다.

# 개선 결과

총 9개의 개선 과제를 도출, 6개의 과제 수행, 5개의 개선 사항이 운영 서비스에 적용되었다. 아래는 개선을 진행하며 변화를 기록한 내용이다. 한정된 횟수로 진행된 시험이니 속도의 변경은 추세로만 확인하고, 정확한 변경 사항은 링크한 WebPageTest의 결과를 참고하기 바란다.

## 최적화 단계 별 성능 변경(ms)

측정점Page첫방문재방문WebPageTest
최적화 배포 전
단품운영
2200
1800
최적화 배포 전
단품sm14
2600
1900
스크립트 우선순위 최적화
단품sm18
2300
1900
스타일 인라이닝
단품sm18
2400
1900
스크립트 지연 로딩
단품sm18
2200
2000
프리로드
단품sm18
1700
1600
선제 연결
단품sm18
1600
1500
최적화 배포 후
단품운영
1500
1300
최적화 배포 전
운영
4300
3900
최적화 배포 전
sm14
4100
3900
스크립트 우선순위 최적화
sm18
3700
3600
스타일 인라이닝
sm18
3700
3700
스크립트 지연 로딩
sm18
6000
3900
프리로드
sm18
2700
3100
이미지 지연 로딩 + 프리페치
sm18
2700
2600
선제 연결
sm18
2700
2600
최적화 배포 후
운영
2100
1900

## 경쟁사 속도 비교

### 단품 상품 페이지

image

### 딜/기획전 상품 페이지

image

### 경쟁사 상품 페이지 로딩 속도(ms)

Name단품 첫방문단품 재방문딜 첫방문딜 재방문단품 테스트딜/기획전 테스트
GS홈쇼핑
2,200
1,800
4,300
3,900
I 홈쇼핑
2,800
1,800
3,200
2,300
G 홈쇼핑
2,200
1,000
2,700
1,200
F 홈쇼핑
2,000
1,800
2,100
1,400
J 홈쇼핑
3,700
1,800
5,300
2,600
D 홈쇼핑
1,500
900
1,600
1,500
C 홈쇼핑
1,400
800
1,700
800
A 홈쇼핑
1,500
900
1,100
700
H 홈쇼핑
1,900
1,000
2,500
2,300
B 홈쇼핑
1,600
1,200
1,300
1,100
E 홈쇼핑
2,800
1,300
2,000
1,100

### 이커머스 상품 페이지 로딩 속도(ms)

홈쇼핑을 제외한 이커머스 사이트들은 딜 페이지를 찾을 수 없는 경우가 있어, 단품 페이지 기준으로만 측정했다.

image

### 이커머스 상품 페이지 로딩 속도(ms)

Name상품 첫방문상품 재방문단품 테스트
K 커머스
3,000
1,700
L 커머스
1,700
1,100
M 커머스
2,300
1,400
N 커머스
2,100
1,400
O 커머스
2,900
2,400
P 커머스
2,200
900
Q 커머스
1,900
1,900
R 커머스
1,800
1,200
S 커머스
5,500
2,100

# 마치며

이번 프로젝트를 통해 많이 개선했지만, 여전히 경쟁사와 비교해 빠르다 말하기 힘든 속도이다. 이번 프로젝트는 한정된 작은 범위 내에서의 변경인 만큼, 앞으로 개선해야 할 아래와 같은 사항들이 여전히 남아있다.

GSShop 웹 속도 개선은 COE로서 그간 스타트업들과 이 프로젝트를 해왔던 경험이 없이는 할 수 없었던 프로젝트라고 생각한다. 앞으로는 스타트업들을 대상으로 웹 속도 모니터링 서비스를 기획하고 있다. 한 명의 개발자로서 GSShop처럼 큰 사이트의 속도 개선 프로젝트를 진행할 수 있는 기회를 얻어 즐겁게 진행한 프로젝트였다. 마지막으로 같이 프로젝트 진행하며 가장 많이 고생한 마이크로 서비스팀의 정진영 매니저님과 지원을 아끼지 않은 COE 팀, 마이크로 서비스팀에 감사의 말을 전한다.