13장. 웹페이지의 성능을 측정하는 다양한 방법
애플리케이션에서 성능 확인하기
create-react-app
- reportWebVitals 함수는 웹에서 성능을 측정하기 위한 함수다.
- 누적 레이아웃 이동(CLS), 최초 입력 지연(FID), 최초 콘텐츠풀 페인트(FCP), 최초 콘텐츠 페인팅(LCP), 첫 바이트까지의 시간(TTFB)을 측정하는 용도로 사용된다.
- 브라우저의 웹페이지 성능을 측정할 수 있는 이유는 PerformanceObserver라는 API를 사용하기 때문이다.
- PerformanceObserver는 웹페이지에서 다양한 성능을 측정할 수 있도록 도와주는 API
create-next-app
- 성능 측정을 할 수 있는 메서드인 NextWebVitalsMetric을 제공한다.
- Next.js에 특화된 사용자 지표도 제공한다.
- Next.js-hydration : 페이지가 서버 사이드에서 렌더링되어 하이드레이션하는 데 걸린 시간
- Next.js-route-change-to-render : 페이지가 경로를 변경한 후 페이지를 렌더링을 시작하는 데 걸리는 시간
- Next.js-render : 경로 변경이 완료된 후 페이지를 렌더링하는 데 걸린 시간
구글 라이트하우스
- 별도의 애플리케이션 코드 수정이나 배포, 수집 없이도 지표를 수집할 수 있다.
- 핵심 웹 지표뿐만 아니라 접근성, PWA, SEO 등 웹 페이지를 둘러싼 다양한 요소들을 측정하고 점검할 수 있다.
- 탐색 모드 : 페이지에 접속했을 때부터 페이지 로딩이 완료될 때까지의 성능을 측정하는 모드 (성능, 접근성, 권장사항, 검색 엔진 최적화)
- 기간 모드 : 실제 웹페이지를 탐색하는 동안 지표를 측정하는 것(흔적, 트리맵)
- 스냅샷 모드 : 탐색 모드와 유사하지만 현재 페이지 상태를 기준으로 분석한다. 페이지 로딩이 아닌 특정 페이지 특정 상태를 기준으로 분석하고 싶을 때 사용한다.
성능
- 웹페이지의 성능과 관련된 지표를 확인할 수 있는 영역이다.
- 핵심 웹 지표인 최초 콘텐츠풀 페인트(FCP), 최초 콘텐츠 페인팅(LCP), 누적 레이아웃 이동(CLS) 이외에도 3가지 추가적인 지표가 있다.
- Time to Interactive : 페이지에서 사용자가 완전히 상호작용(인터렉션)할 수 있을 때까지 걸리는 시간. 상호작용에 걸리는 시간이란
- 최초 콘텐츠풀 페인트로 측정되는 페이지 내 콘텐츠가 표시되는 시점
- 보여지는 페이지 요소의 대부분에 이벤트 핸들러가 부착되는 시점
- 페이지가 유저의 상호작용에 50ms 내로 응답하는 시점
- 이 TTI 지표가 3.8초 이내면 좋음, 3.7초 이내면 보통, 그 이후는 개선이 필요한 것으로 본다.
- Speed index : 페이지가 로드되는 동안 콘텐츠가 얼마나 빨리 시각적으로 표시되는지를 계산한다. 이 지표가 3.4초 이내면 좋음, 5.8초 이내면 보통, 그 이후는 느리다고 판단한다.
- Total Blocking Time : 메인 스레드에서 특정 시간 이상 실행되는 작업, 즉 긴 작업이 수행될 때마다 메인 스레드가 차단된 것으로 간주한다. 메인 스레드에서 실행하는 작업이 50ms 이상 걸리면 이를 긴 작업이라고 간주하고, 이렇게 실행되는 긴 작업을 모아서 Total Blocking Time(총 차단 시간)이라고 한다. 이 시간은 최초에 사용자에게 무언가 콘텐츠를 보여줬을 때(최초 콘텐츠풀 페인트,FCP)부터 상호작용까지 걸리는 시간(TTI) 사이의 작업만 대상으로 한다.
접근성
- 웹 접근성 : 장애인 및 고령자 등 신체적으로 불편한 사람들이 일반적인 사용자와 동등하게 웹페이지를 이용할 수 있도록 보장하는 것
권장사항
- 웹사이트를 개발할 때 고려해야 할 요소들을 얼마나 지키고 있는지 확인
- 보안, 표준모드, 최신 라이브러리, 소스 맵 등
- CSP가 XSS 공격에 효과적인지 확인
- XSS(Cross Site Scripting) : 개발자가 아닌 제3자가 삽입한 스크립트를 통해 공격하는 기법
- CSP(Content Security Policy) : 웹 사이트에서 호출할 수 있는 컨텐츠를 제한하는 정책
- 감지된 JavaScript 라이브러리
- HTTPS 사용
- 페이지 로드 시 위치정보 권한 요청 방지하기
- 페이지 로드 시 알림 권한 요청 방지하기
- 알려진 보안 취약점이 있는 프런트엔드 자바스크립트 라이브러리를 사용하지 않음
- 사용자가 비밀번호 입력란에 붙여넣을 수 있도록 허용
- 이미지를 올바른 가로세로 비율로 표시
- 이미지가 적절한 해상도로 제공됨
- 페이지에 HTML Doctype 있음
- 문자 집합을 제대로 정의함
- 지원 중단 API 사용하지 않기
- 콘솔에 로그된 브라우저 오류 없음
- Chrome Devtools의 issues 패널에 문제 없음
- 페이지에 유효한 소스 맵이 있음
- font-display : optional을 사용하는 폰트가 미리 로드됨
검색 엔진 최적화
- 웹페이지가 구글과 같은 검색엔진이 쉽게 웹페이지 정보를 가져가서 공개할 수 있도록 최적화돼 있는지를 확인하는 것을 의미
- 검색엔진에 최적화돼 있을수록 검색 엔진의 검색결과 우선순위에 높게 나타나며, 사용자가 유입될 가능성이 높아진다.
흔적
- 상세하게 시간의 흐름에 따라 어떻게 웹페이지가 로딩됐는지를 보여준다
트리맵
- 페이지를 불러올 때 함께 로딩한 모든 리소스를 함께 모아서 볼 수 있는 곳
- 웹페이지의 전체 자바스크립트 리소스 중 어떠한 파일이 전체 데이터 로딩 중 어느 정도를 차지했는지를 비율로 확인할 수 있으며, 실제 불러온 데이터의 크기를 확인할 수도 있다.
- 로딩한 리소스에서 사용하지 않은 바이트의 크기를 확인할 수 있는데, 이는 실제로 불러왔지만 사용되지 않은 리소스를 의미한다.
WebPage Test
- WebPage Test에서 제공하는 분석 도구
- Site Performance : 웹사이트의 성능 분석을 위한 도구
- Core Web Vitals : 웹사이트의 핵심 웹 지표를 확인하기 위한 도구
- Lighthouse : 구글 라이트하우스 도구
- Visual Comparison : 2개 이상의 사이트를 동시에 실행해 시간의 흐름에 따른 로딩 과정을 비교하는 도구
- Traceroute : 네트워크 경로를 확인하는 도구
- 한국과 어느 정도 거리가 먼 서버를 기준으로 테스트하기 때문에 크롬 개발자 도구에서 테스트했을 때보다 성능 지표가 좋지 않을 가능성이 매우 높다.
측정 결과 페이지는
- Opportunities & Experiments : 웹 사이트에 대한 평가를 총 3가지로 나눠서 보여준다.
- Is it Quick : 웹사이트가 충분히 빠른지를 평가한다. 여기서 빠름을 나타내는 것은 최초 바이트까지의 시간(TTFB)이 짧은지, 콘텐츠 렌더링이 즉각적으로 일어났는지, 최대 콘텐츠풀 페인트(LCP) 시간이 합리적인지를 확인한다.
- Is it Usable : 웹사이트의 사용성과 시각적인 요소를 확인한다. 콘텐츠 누적 이동(CLS)을 최소화하고 있는지, 상호작용을 빠르게 할 수 있는지, 접근성 이슈가 있는지, 클라이언트 사이드에서 과도하게 HTML을 많이 렌더링하는지 등을 점검한다.
- Is it Resilient : 보안 취약성을 검증한다.
- Observed Metrics : 최초 바이트까지의 시간, 렌더링 시작에 소요되는 시간, 최초 콘텐츠풀 페인트 등 측정할 수 있는 다양한 시간 지표에 대해 나타낸다.
- Individual Runs : 기본적으로 WebPageTest는 3번의 테스트를 돌려서 평균값을 보여주는데, 각 실행별로 어떠한 결과를 보여주는지 확인할 수 있다.
Opportunities & Experiments
- 최초 바이트까지의 시간(TTFB)을 점검한다.
- 렌더링을 블로킹하는 자바스크립트가 있는지 확인한다.
- 렌더링을 블로킹하는 CSS가 있는지 확인한다.
- 최초 콘텐츠풀 페인트가 2.5초 이내인지 확인한다.
- 주요 영역에 게으른 로딩되는 이미지가 있는지 확인한다.
- 주요 영역 외에 이미지가 게으르게 로딩되는지 확인한다.
- 문자의 노출을 지연시키는 커스텀 폰트가 있는지 확인한다.
- 제3자 호스트에서 폰트를 불러오는지 확인한다.
- 실제로 사용하지 않는 리소스를 rel=preload로 불러오지 않는지 확인한다.
- HTTP 리다이렉트되는 리소스가 없어야한다.
- 최초로 다운로드받은 HTML과 최종 결과물 HTML 사이에 크기 차이가 적어야 한다.
- Is it Usable
- 이미지 비율 부재로 인한 레이아웃 이동 가능성 여부를 확인한다.
- 어떤 이유에서건 메인 스레드가 장시간 멈춰 있어서는 안 된다.
- meta: viewport가 적절하게 삽입돼 있어야 한다.
- 접근성 이슈가 있는지 확인한다.
- 최초로 다운로드받은 HTML과 최종 결과물 HTML 사이에 크기 차이가 적어야 한다.
- Is it Resilient
- 렌더링을 막는 제3자 라이브러리 요청이 없어야 한다.
- Snyk에서 검출된 보안 위협이 없어야 한다.
- 모든 요청은 HTTP가 아닌 HTTPS를 거쳐야 한다. HTTPS는 데이터의 무결성을 담보하고, 사용자의 개인정보를 보호하며, 보안 위협으로부터 지켜주므로 반드시 HTTPS를 사용해야 한다.
- 최초로 다운로드한 HTML과 최종 결과물 HTML 사이에 크기 차이가 적어야 한다.
Filmstrip
- 웹사이트를 마치 필름을 보는 것처럼 시간의 흐름에 따라 어떻게 웹사이트가 그려졌는지, 또 이때 어떤 리소스가 불러와졌는지 볼 수 있는 메뉴다.
- Filmstrip의 그래프를 직접 확인하면 어떤 것이 성능에 영향을 미치는지, 개선점은 무엇이 있는지를 확인할 수 있다.
Details
- Filmstrip에서 보여준 내용을 자세하게 보여주는 영역
Web Vitals
- 최초 콘텐츠 페인팅(LCP), 누적 레이아웃 이동(CLS), 총 블로킹 시간(TBT)에 대한 자세한 내용을 확인할 수 있다.
Optimizations
- 리소스들이 얼마나 최적화돼 있는지 나타낸다.
- 확인 가능한 내용은
- Keep-Alive 설정으로 서버와의 연결을 계속 유지하고 있는지
- Gzip으로 리소스를 압축하고 있는지
- 이미지를 적절하게 압축했는지
- Progressive JPEG으로 jPEG 이미지를 렌더링하고 있는지
- 리소스 캐시 정책을 올바르게 수립돼 있는지
- 리소스가 CDN(Content Delivery Network)을 거치고 있는지
Content
- 웹사이트에서 제공하는 콘텐츠, 애셋을 종류별로 묶어 통계를 보여준다.
- 애셋 종류별 크기와 로딩 과정을 확인할 수 있으며, 시간의 흐름에 따라 렌더링을 거치면서 또 어떻게 애셋을 불러오는지도 확인할 수 있다.
Domains
- Content 메뉴에서 보여준 애셋들이 어느 도메인에서 왔는지를 도메인별로 묶어서 확인할 수 있다.
- 해당 도메인별로 요청한 크기는 어느 정도인지도 확인할 수 있다.
Console Log
- 사용자가 웹페이지에 접속했을 때 console.log로 무엇이 기록됐는지를 확인할 수 있다.
Detected Technologies
- 웹사이트를 개발하는 데 사용된 기술을 확인할 수 있는 메뉴
Main-thread Processing
- Processing Breakdown : 메인 스레드가 어떤 작업을 처리했는지 확인할 수 있다. 메인 스레드의 작업을 크게 스크립트 실행, 레이아웃, 리소스 로딩, 페인팅, 기타의 총 다섯 가지로 분류해서 알려준다.
- Timing Breakdown : 유휴 시간을 포함해 메인 스레드의 작업을 확인할 수 있다.
Lighthouse Report
- 구글 라이트하우스 리포트를 확인할 수 있다.
기타
- Image Analysis : Cloudinary로 연결되며, 해당 웹사이트에 어떠한 이미지가 있는지, 그리고 이 이미지들이 최적화된다면 리소스를 어느 정도 아낄 수 있는지 보여준다.
- Request Map : 웹사이트에서 요청이 어떻게 일어나고 있는지를 시각화 도구로 보여준다.
- Data Cost : 각 국가별로 가장 저렴한 요금제를 기준으로 이 웹사이트를 로딩했을 때 실제로 얼마나 가격이 드는지를 확인
- Security Score : 해당 사이트의 보안 취약점에 대해 알려준다.
크롬 개발자 도구 - 성능 통계 탭
- Performance Insights : 웹사이트의 성능을 자세하게 확인할 수 있는 도구
- 한 가지 눈에 띄는 것은
Throttling
인데, 이는 고의로 네트워크와 CPU 속도를 지연시키는 기능이다. 속도를 고의로 지연시켜 개발자의 최신 디바이스 성능이 아닌, 일반적인 모바일 사용자의 상대적으로 열악한 환경을 재현할 수 있다.
Insights
- 성능을 측정하는 기간 동안 발생한 이벤트 중 눈여겨봐야 할 내용을 시간의 흐름에 따라 모아서 보여준다.
- 핵심 웹 지표 : 핵심 웹 지표인 최초 콘텐츠풀 페인트(FCP), 최초 콘텐츠 페인팅(LCP), Dom Content Loaded가 언제 일어났는지 보여준다.
- Performance Measure : User Timing API로 측정한 지표들을 확인할 수 있다.
- Long Task : 메인 스레드에서 실행되는 데 오랜 시간으로 분류된 긴 작업을 의미한다.
- Render blocking CSS : 렌더링을 막는 CSS. 이를 조치할 수 있는 방안은
- 중요하지 않은 스타일이라면 link rel=”preload” as “style”로 스타일을 비동기적으로 요청한다.
- 미디어 쿼리를 활용해 디바이스에 필요한 스타일만 불러온다.
- CSS 내부의 띄어쓰기, 줄바꿈 등을 압축해 최대한 크기를 줄인다.
- Forced Style recalculation : 이미 스타일이 한번 계산된 이후에 어떠한 이유로 스타일이 다시금 계산되는 작업이 강제로 발생했음을 의미한다.
메인 메뉴
- 성능을 측정하는 기간 동안 무슨 일이 일어나는지 확인할 수 있는 다양한 기능을 제공한다.
크롬 개발자 도구 - 성능 탭
네트워크
- 성능 측정 기간 동안에 발생한 모든 네트워크 요청을 확인할 수 있다.
- 네트워크 요청은 각 색깔에 따라 어떠한 종류의 요청인지 확인할 수 있다.
- 파란색 : HTML
- 보라색 : CSS
- 노란색 : 자바스크립트
- 초록색 : 이미지
- 회색 : 기타
- 폰트
- JSON 등
- 위에 있는 요청이 우선순위가 높은 요청이다.
- 그래프를 읽는 방법은
- 왼쪽 선은 연결을 시작되기 위한 기간을 나타낸다.
- 대표 색상의 막대 그래프 중 색이 더 연한 왼쪽은 요청을 보내고 최초 바이트가 오기까지의 대기 시간을 의미한다.
- 대표 색상의 막대 그래프 중 색인 진한 오른쪽은 콘텐츠를 다운로드하는 데 걸리는 시간을 의미한다.
- 그리고 마지막에 거의 안 보이는 오른쪽 선은 메인 스레드의 응답을 기다리는 시간인데, 이는 네트워크의 소요 시간에 포함하지 않는다.
Web vitals
- 핵심 웹 지표 시점을 확인할 수 있는 영역
소요 시간과 기본
- 시간의 흐름에 따라 메인 스레드의 작업은 어떻게 이뤄졌는지, 또 자바스크립트 힙 영역은 어떻게 변화하는지 등을 확인할 수 있다.