글을 시작하며
많은 프론트엔드 개발자들은 본인이 만든 웹 페이지가 버벅임 없이 보여지고 많은 사람들에게 노출되기를 바랄 것입니다.
이를 위해서는 웹 페이지의 성능을 개선하는 것이 필요합니다.
우리는 Lighthouse라는 툴을 이용해서 웹 페이지의 성능을 쉽게 측정할 수 있습니다.
지금부터 웹 페이지의 성능을 높이기 위해서는 어떠한 작업이 필요할지 힌트를 얻기 위해 Lighthouse의 지표들에 대해 알아보도록 하겠습니다.
지표에 대한 설명보다는 최적화를 위해 Next.js 프로젝트에 적용했던 방법들이 궁금하시다면 이 포스팅을 참고해주시기 바라겠습니다.
Lighthouse
Lighthouse는 웹 페이지 성능을 측정하여 5가지 항목에 대한 점수를 보여줍니다.
사실 Lighthouse를 사용하지 않고도 Performance 탭이나 Network 탭을 이용해서 이벤트 발생 시점이나 파일 크기를 분석할 수도 있습니다.
그렇다면 왜 Lighthouse를 사용해야 할까요? 🤔
웹 애플리케이션이 커지면서 큰 스크립트와 많은 이벤트 등으로 성능을 측정하는 기준이 모호해지게 되었고 사용자 기준의 측정 방식이 등장하였습니다.
사용자 기준의 성능 측정
은 사용자에게 의미 있는 콘텐츠가 처음 보이는 시점이 빠를수록
성능이 좋다고 판단합니다.
사용자 기준 성능 측정
예를 들어, 위의 두 페이지는 DOMContentLoaded, load 이벤트가 같은 시점에 발생했습니다. 하지만 사용자는 상단의 페이지에서 컨텐츠를 더 빠르게 볼 수 있기 때문에 로딩이 훨씬 빠르다고 느낍니다.
따라서 Lighthouse에서는 이와 같이 사용자가 로딩이 빠르다, 느리다를 느낄 수 있는 여러 순간을 정의하고 성능을 측정하는 지표로 사용합니다.
사용법
사용 방법은 크롬 확장 프로그램을 설치한 다음 Chrome Extension 아이콘을 눌러서 사용하거나, 개발자 도구에서 Lighthouse 탭을 통해 사용할 수도 있습니다.
Performance
Performance는 사용자가 얼마나 빠르게 컨텐츠를 인식하는지
를 평가하는 지표입니다.
성능 점수는 6가지 점수들의 가중 평균값으로 계산됩니다.
-
LCP(Largest Contentful Paint) - 25%
가장 큰 콘텐츠
를 렌더링 하는데 걸리는 시간
-
TBT(Total Blocking Time) - 30%
- 마우스 클릭 등
사용자 입력에 페이지가 응답하지 못하도록 차단된
총 시간 - FCP와 TTI 사이에 긴 시간이 걸리는 작업들을 모두 기록하여 측정합니다.
- 마우스 클릭 등
-
CLS(Cumulative Layout Shift) - 15%
- 로딩 후 폰트 크기 변경 등
예상치 못한 레이아웃 이동
에 대한 점수
- 로딩 후 폰트 크기 변경 등
-
TTI(Time to interactive) - 10%
- 사용자가 페이지와 완전하게 상호작용할 수 있을 때까지 걸리는 시간
-
FCP(First Contentful Paint) - 10%
- 최초의 DOM 콘텐츠를 렌더링하는데 걸리는 시간
-
Speed Index - 10%
- 콘텐츠가 시각적으로 표시되는 진행 속도를 측정
Next.js의 Performance 개선 방법
Performance 성능을 개선하기 위해서 다음과 같은 방식을 사용해볼 수 있습니다.
-
이미지 최적화
- 웹 페이지에서는 이미지가 대부분 가장 큰 공간과 용량을 차지하기 때문에
LCP를 개선
하기 위해서는 이미지 최적화가 중요합니다. - 압축률이 좋은 avif, webp 파일 형식 사용
- next/image를 사용해서 lazy 속성으로 필요할 때 불러오거나, priority 속성으로 가장 먼저 불러오기
- 웹 페이지에서는 이미지가 대부분 가장 큰 공간과 용량을 차지하기 때문에
-
폰트 최적화
- 늦은 폰트 로딩은
컨텐츠를 늦게 표시
하는데 영향을 주고레이아웃 움직임
을 유발할 수 있기 때문에 FCP나 CLS 성능에 영향을 줄 수 있습니다. - font-display: swap 속성으로 폰트 로딩 전에 시스템 폰트를 보여주어서 빈 화면을 방지합니다.
- next/font를 사용하면 네트워크 요청 없이도 바로 font를 사용할 수 있습니다.
- 늦은 폰트 로딩은
-
번들 최적화
- JavaScript 실행 시간을 단축하면
사용자가 더 빨리 상호작용
을 할 수 있게 되기 때문에 TBT나 TTI 성능을 개선할 수 있습니다. - dynamic import를 이용하면 현재 필요한 코드만 다운받을 수 있기 때문에 번들 크기를 줄일 수 있습니다.
- JavaScript 실행 시간을 단축하면
-
리소스 캐싱
- 캐싱을 이용하면 리소스 로딩 속도가 빨라집니다.
- 서비스 워커를 사용하여 HTML, JS, 이미지 등의 리소스를 브라우저에 캐싱할 수 있습니다.
Performance 성능 최적화 방법을 간단하게 정리해보았습니다. 자세한 적용 방법은 다음 포스팅에서 다뤄보도록 하겠습니다 🔥
이제 다른 4가지 항목에 대해서도 알아보겠습니다.
Accessibility
Accessibility는 웹의 접근성을 평가하는 지표입니다.
예를 들어서 시각 장애인들도 이미지에 대한 정보를 얻을 수 있게 <img>
태그에 alt
속성이 있는지, 배경색과 텍스트의 대비가 충분한지와 같은 항목을 확인합니다.
Best Practices
Best Practices는 웹에 대한 표준 모범 사례를 따르고 있는지 평가하는 지표입니다.
가령 콘솔에 오류가 출력되진 않는지, 사용하지 않는 API를 호출하고 있지는 않는지, HTTPS를 통해 페이지에 접근할 수 있는지 등을 확인합니다.
SEO
SEO는 검색 엔진에 대해 최적화된 순위 결과를 가지고 있는지 평가하는 지표입니다.
meta 요소가 잘 작성되어 있는지, robots.txt 파일이 유효한지, 컨텐츠를 읽는데 글꼴 크기가 무리가 없는지 등을 고려합니다.
PWA(Progressive Web App)
PWA는 Progressive Web App을 정의하는 기준에 따라 평가하는 지표입니다. 결과는 합격 또는 실패로 나뉩니다.
웹을 PWA로 이용하는데 문제가 없는지에 대한 요소를 평가합니다.
Lighthouse 성능 개선 가이드
이제 Lighthouse의 지표들과 측정 기준에 대해 알게 되었습니다.
그렇다면 우리는 어떻게 이 지표들을 개선할 수 있을까요?
Lighthouse의 Opportunities 항목을 확인하면 어떤 요소에서 시간이 많이 소요되는지, 어떻게 최적화 할 수 있을지 해결책을 제시해줍니다.
하지만 이렇게만 봐서는 JavaScript 코드 크기를 어떻게 줄여야 할 지 조금 막막하네요 🤯
Wepback Bundle Analyzer를 사용해서 어떻게 개선할 수 있을까요?
다음 포스팅에서는 제가 Next.js에서 성능을 개선하기 위해 시도했던 방법들을 소개해드리고자 합니다! 이번 포스팅은 사실 다음 포스팅에서 다룰 성능 최적화를 이해하기 위해 필요한 개념들을 다룬 글입니다.
이제 기초 공사는 끝났으니 최적화에 대한 이해가 더 쉬워지실 겁니다.
그럼 다음 포스팅에서 뵙겠습니다 😁
Next.js 쉽게 이해하기 🔍