Chrome Lighthouse를 활용한 웹 최적화

최원빈·2022년 10월 22일
3
post-thumbnail

몇개월간 쉬지않고 달려온 회사는, 눈에 보이는 빠른 성과가 필요했다.

웹의 성능을 올리기보다는, 다양한 기획과 서비스를 바꿔가며 소비자들에게 제공해보며 여러 실험을 진행했다.

같은 광고를 진행했을 때, 어떤 기획에 사람들이 많이 들어오는지, 클릭률이 높은지, 회원가입을 많이하는지를 알아보는 실험이 우선적으로 필요했다.

웹의 성능을 향상시켜도, 다른 실험으로 기획이 틀어지게 되면 처음부터 다시 만들어야했으니 나도 성능보다는 시간에 맞춰 개발했다.

그러던 중 콘텐츠적인 부분에 있어 장기적인 실험을 하게 되었고, 프론트 팀은 여유가 남아 한동안 미뤄뒀던 성능개선을 진행하기로 마음먹었다.

내가 느끼기에는 속도가 우리의 랜딩페이지의 로딩 속도가 느린 편이라고 생각했고, 광고이탈률을 높이는 데 한 몫 했다고 생각했기에 회의때 언급하고 개선하기로 마음먹었다.


프로젝트에는 눈에 보이는 결과물이 있어야했기에 웹 성능을 객관적으로 분석해주는 Chorme Lighthouse를 사용해 목표를 잡았다.

현재 50점대의 퍼포먼스.. 모바일 환경에서는 20점대까지 나왔다..

1주일동안 모든 디바이스와 페이지에 대해서 최소 60점 이상의 성능을 가져가기로 목표를 정하고, 필요한 부분을 공부해가며 적용했다.

여기서 알려주는 기준들은 전부 UX에 있어 크리티컬하다.

1. Webp 확장자 사용하기


png, jpg 쓰지 마세요!

랜딩페이지는 다른 페이지들보다 유난히 사진이 많이 필요하다.
여러 정보들을 화려하게 보여줘야했기에 사진이 많이 들어갔고, 개발속도를 위해서 assets에 담아 보여주곤 했다.

이를 해결하기 위해, 빌드 파일에 모아뒀던 asset들을 S3 CloudFront에 올리고, AWS Lambda를 사용해 webp로 쉽게 변환해서 요청할 수 있었다.

Nodejs환경에서 동작하는 서비스였지만, 예제만 가져다 써도 잘 동작해서 과정을 이해할 필요는 없었다.

<img src={item.thumbnail} alt="배너 썸네일"/>

// 쿼리 파라미터로 손쉽게 변경 가능했다.
<img src={`${item.thumbnail}?webp="true"`} alt="배너 썸네일"/>

webp 확장자를 지원하지 않아 <picture /> 태그로 분기처리하는 예제가 많던데, IE말고는 잘 지원하고 있어 불필요하다 생각해 굳이 처리하지 않았다.

2. 이미지 리사이징하기

우리 프로젝트는 어떻게보면 모바일 환경이 메인인, 반응형 프로젝트였다.

하지만 이미지를 PC기준으로 사용하게 되면 모바일 환경에서 요청하는 이미지가 불필요하게 커지는데, 사이즈가 조금만 늘어나도 이미지의 용량은 기하급수적으로 커진다.

이 또한 Lambda에서 제공하는 기능으로 리사이징을 해결할 수 있었고, 화면 사이즈에 맞게 다른 크기의 이미지를 요청할 수 있게끔 클라이언트 단에서 처리해주면 해결할 수 있었다.

<img src={
    isLarge 
      ? `${item.thumbnail}?webp="true&w=200&h=100"`
      : `${item.thumbnail}?webp="true&w=100&h=50"`
  } alt="배너 썸네일"/>

3. 이미지 lazy loading하기

<img /> 태그는 loading이라는 어트리뷰트가 존재한다.

loading="lazy" 를 추가하게 되면, 이미지를 최초에 로딩하지 않고 Viewport에 가까워졌을 때 로딩하기 시작하는데, 완전히 보여야 로딩하는 것도 아니고 적당히 거리가 있을때 로딩해줘서 사용하는 입장에서는 전혀 불편하지 않다.

맨 위 이미지를 제외하고, 모든 이미지에 해당 어트리뷰트를 추가해주었다.

<img 
  src={
    isLarge 
      ? `${item.thumbnail}?webp="true&w=200&h=100"`
      : `${item.thumbnail}?webp="true&w=100&h=50"`
  } 
  alt="배너 썸네일"
  loading="lazy" />

최신 브러우저라면, 전부 지원하는 스펙이다.

4. 안 쓰는 JS 제거하기

페이지를 로딩했을때 불러온 번들 파일에 추가되었지만, 지금 페이지에서 사용되지 않는 JS가 너무 많다고 한다.

미사용중인 라이브러리를 전부 지웠지만, 번들링의 특징때문에 다른 페이지에서 사용되는 라이브러리도 최초 로딩 중에 전부 갖고오게 된 것인데..

Chrome Lighthouse가 여기서 빛을 발한다. React를 사용중인 것을 확인하고, React.Lazy() 를 사용해 코드를 스플리팅 하라고 알려준다.

SPA의 장점인 빠른 페이지 넘김은 좋지만, 우리의 사용자 인터렉션 실험 과정에서 중요한 것은 구매 신청까지만의 과정이므로 수강플랫폼과, 잘 들어가지 않는 프로필화면 등을 스플리팅하기로 결정했다.

헤더, 푸터처럼 반드시 렌더링되는 컴포넌트와,
메인, 상세페이지 처럼 SPA의 끊기지 않는 부드러움이 필요한 부분은 냅두고, 전부 스플리팅했다.


여기에 빠진 alt 속성 추가와 같은 짜잘한 수정을 더해서 나온 결과는..

생각보다 어마무시했다.

눈에 보이는 점수도 높아졌지만, 아래 속도들의 변화가 확연했다.

이전 성능

전체 blocking time이 90%가 줄고,
페이지가 그려지는 시간과, 첫 페이지 동작 시점도 2초 가량 빨라졌다.

손이 많이 가는 복잡한 작업을 한 게 아님에도 불구하고, 확실한 성능의 개선을 이뤘다.

이번 개선이 앞으로의 실험에 긍정적인 영향을 끼칠 것이라 기대한다.

profile
FrontEnd Developer

1개의 댓글

comment-user-thumbnail
2022년 10월 23일

img 태그에 loading 속성은 첨 알았네요 ㄷㄷ... 최적화 글 잘 읽었습니다~👍

답글 달기